Introduction
Update of explore-JULES-ES-1p0.Rmd that uses the new packages and functions
We build and test gaussian process emulators, perform a sensitivity analyis, and constrain the input space of Jules.
Andy thinks there might be mileage in analysing the atmospheric growth, which is here. /home/h01/hadaw/Research/ES_PPE/Oct20
At the moment, this vignette is hampered by the fact that emulators are failing on a few of the outputs which represent change over the historical period. The emulator is fine for predicting absolute values in the modern period.
Andy would like to see timeseries of: cVeg, cSoil and nbp, npp in GtC and GtC/yr.
Preliminaries
Load libraries, functions and data.
Carbon budget data
Section 2.5 in Friedlingstein et al. describes how the land carbon sink is estimated.
Variables available for analysis
Load a single ensemble member to examine contents
Plot timeseries of aggregated global timeseries


Where did the model fail to run?
(“probability of run failure” Could be an interesting project - logit transformation for probability of run failure? Some other ML like SVM?
There are clear run failure thresholds in the parameters rootd_ft_io and lai_max, and quite strong visual indications that a_wl_io and bio_hum_cn matter.
NEXT, histograms of failure with the LHS value


Could try an SVM, logistic regression or similar.
Testing Gaussian Process emulators
NPP as a test
First, use mean NPP as an example. How does NPP respond to each parameter? NAs are removed, but zero values are still included.


Relationship between modern NPP and change since 1850.
Some outputs (e.g fLuc, fHarvest) have an almost perfect 1:1 relationship between modern value and change, some (nbp, npp, treeFrac) quite or moderately strong, and some (csoil, cveg) very weak or non-existant.

A clear threshold in the F0 parameter for NPP
It appears that this ensemble is less “clear cut” in having an output that clearly distinguishes between “failed” (or close to it), and “not failed”.
Having said that, having an F0 over a threshold seems to kill the carbon cycle, as before. Here, we’ve set a threshold of 0.9 (on the normalised scale) for F0, and we remove members of the ensemble with a larger F0 than that when we build emulators.
[1] "nbp_lnd_sum"
[1] "Carbon Mass Flux out of Atmosphere Due to Net Biospheric Production on Land"
[1] "year"
[1] "year"
[1] "nbp_lnd_mean"
[1] "Carbon Mass Flux out of Atmosphere Due to Net Biospheric Production on Land"
[1] "fLuc_lnd_sum"
[1] "Net Carbon Mass Flux into Atmosphere Due to Land-Use Change"
[1] "fLuc_lnd_mean"
[1] "Net Carbon Mass Flux into Atmosphere Due to Land-Use Change"
[1] "npp_nlim_lnd_sum"
[1] "Net Primary Production on Land as Carbon Mass Flux"
[1] "npp_nlim_lnd_mean"
[1] "Net Primary Production on Land as Carbon Mass Flux"
[1] "cSoil_lnd_sum"
[1] "carbon mass in model soil pool"
[1] "cSoil_lnd_mean"
[1] "carbon mass in model soil pool"
[1] "cVeg_lnd_sum"
[1] "carbon mass in vegetation"
[1] "cVeg_lnd_mean"
[1] "carbon mass in vegetation"
[1] "landCoverFrac_lnd_sum"
[1] "Plant Functional Type Grid Fraction"
[1] "landCoverFrac_lnd_mean"
[1] "Plant Functional Type Grid Fraction"
[1] "fHarvest_lnd_sum"
[1] "Carbon Mass Flux into Atmosphere Due to Crop Harvesting"
[1] "fHarvest_lnd_mean"
[1] "Carbon Mass Flux into Atmosphere Due to Crop Harvesting"
[1] "lai_lnd_sum"
[1] "leaf area index"
[1] "lai_lnd_mean"
[1] "leaf area index"
[1] "rh_lnd_sum"
[1] "Total Heterotrophic Respiration on Land as Carbon Mass Flux"
[1] "rh_lnd_mean"
[1] "Total Heterotrophic Respiration on Land as Carbon Mass Flux"
[1] "treeFrac_lnd_sum"
[1] "Fractional cover of each surface type"
[1] "treeFrac_lnd_mean"
[1] "Fractional cover of each surface type"
[1] "c3PftFrac_lnd_sum"
[1] "Percentage Cover by C3 Plant Functional Type"
[1] "c3PftFrac_lnd_mean"
[1] "Percentage Cover by C3 Plant Functional Type"
[1] "c4PftFrac_lnd_sum"
[1] "Percentage Cover by C3 Plant Functional Type"
[1] "c4PftFrac_lnd_mean"
[1] "Percentage Cover by C3 Plant Functional Type"
[1] "shrubFrac_lnd_sum"
[1] "Percentage Cover by Shrub"
[1] "shrubFrac_lnd_mean"
[1] "Percentage Cover by Shrub"
[1] "baresoilFrac_lnd_sum"
[1] "Bare Soil Percentage Area Coverage"
[1] "baresoilFrac_lnd_mean"
[1] "Bare Soil Percentage Area Coverage"
[1] "residualFrac_lnd_sum"
[1] "Percentage of Grid Cell That Is Land but neither Vegetation Covered nor Bare Soil"
[1] "residualFrac_lnd_mean"
[1] "Percentage of Grid Cell That Is Land but neither Vegetation Covered nor Bare Soil"


Level 1 constraint - remove ensemble members with F0 above threshold
The level 1 constraint removes any input with F0 greater than 0.9 (normalised), which removes many of the zero-carbon-cycle members up front. There are 424 ensmble members remaining.
This does constraint sequentially, which may not be a good idea.

Comparison of level 0 and level 1 emulators for NPP (modern value)

# Plot the regular km emulator. Doesn’t look great.

Leave-one-out summaries of NPP emulators
Constrain first and then do sensitivity analysis?
The problem with doing constraint first is that you end up with a non-hypercube shaped input space (corners have been knocked off by constraint), which is not ideal. We might therefore want different sensitivity measures for pre- and post-constrained ensemble.
Initial sensitivity Matrix
It looks as though bwl_io is very influential across a number of variables, even though it didn’t appear that interesting in the parginal plots. Why is that?
Re-examine bwl_io
A closer look at bwl_io now that the impact of f0_io has been removed shows a large number of “zero” NPP when bwl_io is at low values, which could well be the source of apparent sensitivity.
Take only higher values of bwl_io for the next round of constraints.
History matching and generation of new ensemble members
To use History Matching, we need to specify targets for various model outputs. We treat these targets as “observations” with an uncertainty where a model run marked as “implausible” (beyond 3sd) matches the hard boundaries previously identified by A. Wiltshire as being desirable.
Choose the centre of the (implied) uniform distribution. cs_gb.target = (3000 - 750) / 2 = 1125 cv.target = (800 - 300) / 2 = 250 npp_n_gb.target = (80 - 35) / 2 = 22.5
nbp.target = 0 (gpp.target = 75) (runoff.target = 1)
(to do: visualise implausibility of design and loo emulated values of design as histogram)
visualise the constraints
Timeseries that match the constraints.
Plot the original ensemble, plus the stuff that matches the constraints. Include anomalies. “Level 2” constraints are broad constraints produced by AW “Level 3” constraints are tighter constraints from citeable sources produced by ER.
We find that adding a constraint to level 2 constrains the behaviour of the soil carbon pool, but not the vegetation carbon pool. Probably not a surprise, given the Soil Carbon pool (and changes) are much larger than the vegetation carbon pool.
Atmospheric growth
We can calculated the atmospheric growth as Fossil fule emissions (GCB) - Ocean uptake (GCB) - net land flux (JULES NBP)
Conversely, we can calculate the land uptake as NBP = FF - ocean - ag (Do we have AG in JULES?)
another way to calclulate atmospheric growth
These two methods give very similar outcomes, bar an outlier.
Total land carbon change (incorrect)
We plot the JULES total land carbon change from 1850, together with “observations” from the Global Carbon Budget (Friedligstein et al, 2020). The “observations are the cumulative sum of the ‘land sink’ column on the”historical observations tab of the data from the paper. It states “The land sink is the average of several dynamic global vegetation models that reproduce the observed mean total land sink of the 1990s.”
Land carbon Sink?
I think to make a fair comparison, we might need to take the diff of the anomaly (or just the timeseries), as the above represents the total change since 1850, and I think all the “land sink” stuff looks at the year-to-year changes.
Identify parts of parameter space where the land carbon sink is at its maximum
What do these parts of parameter space tell us about what we need to do to have the model reproduce reality?
what parts of parameter space are the closest?
Augment the design.
The function addNroyDesignPoints builds an emulator for each model output in Y. It compares the output of each emulator at a number of candidate desin points, and chooses a space-filling set of them that that are Not Ruled Out Yet (statistically close to the observation at Y_target).
Write the augmented design
The function write_jules_design here simply takes the points calculated by addNroyDesignPoints and writes them to configuration files.
Check the design
Check that the augmented design produces what we expect. New ensemble members should be somewhat constrained within the boundaries of the original design, if the comparison to data offers any constraint.
Visualise the predicted outputs at the NROY points of the old design, and the new suggested design.
Visualising the emulated outputs at the proposed new design points.
Interestingly, these aren’t perfectly within the original hard boundaries set by Andy, even though I’ve set those boundaries to be the +- 4 standard deviation threholds in the History Match. I suggest this is because there is model discrepancy, and that there is considerable wriggle room induced from emulator uncertainty.
In particular, it appears that vegetation carbon is difficult to keep high, and that many NROY proposed members have a fairly low vegetation carbon. This might need a discrepancy term, or adjusting in some other way. It certainly needs exploring, and a OAAT plot might give clues as to the parameters to choose.
How good are the four emulators that we’ve built? Are there biases? (there’s no real evidence of this)
One-at-a-time sensitivity analysis for understanding model response
It’s obviously hard to maintain a high vegetation carbon in particular. What parameter values might you choose to do this, and what might be the trade-offs you have to make?
First, what parameters affect vegetation carbon and how? How sure are we about that?
What might be the trade-offs for a high (or accurate) vegetation carbon? are they acceptable? Plot the oaat sensitivity of the other 3 outputs we’re calibrating on.
What do the emulators make of the design points which actually make Andy’s “hard boundary” criteria? If we leave them out, do they still place the output within the hard boundaries?
Check the emulators that produce the new design
Do a leave-one-out cross validation of points inside the hard boundaries using the wave1 fits.
We see in the leave-one-out analysis that the emulator is consistently under-predicting the vegetation carbon (though the uncertainty estimate often covers the actual value).This suggests (1) that there isn’t really a huge problem with a model discrepancy (or at least that isn’t the only problem), and (2) the history matching is working as it should, and taking into account a not-great emulator.
Compare the straight km with a two-step emulator
Is a two-step emulator any better at emulating those crucial points which fall within aw’s hard boundaries? First, create a list of emulator fits.
It doesn’t appear that the two-step emulator (here plotted in red) is doing any better than the regular emulator.
Two other things I can think of to check: 1) how about using “multistart” to choose different starting conditions for optimising the emulators and 2) Using a flat prior for the mean function rather than a linear prior.
Exploring new constraints
Input from Eddy Robertson:
“We can assume that the majority of vegetation carbon is stored in tree trunks so, the carbon density of trees is approximately (cVeg_lnd_mean / treeFrac_lnd_mean). Although I suppose it’s possible that in the PPE the shrubs have become tree-like, so it might be interesting to plot cVeg_lnd_mean versus (shrubFrac_lnd_mean + treeFrac_lnd_mean) as well. The first question is whether cVeg_lnd_mean increases linearly with treeFrac_lnd_mean. Then if this turned out to be interesting, we could produce a treeCVeg_lnd_mean output.”
Is the range of carbon densities narrower in the “hard boundary” set?
Now that we have constraints, we can explore their effect on the output
How much does constraining an output constrain other outputs?
For example, what effect has the AW “hard boundary” constraint produced on ranges of the other (marginal) outputs? Which constraint is doing the majority of the work?
A function to find the proportion of output space that is removed (or retained) when applying a constraint.
All constraints together take the normalized range of all the outputs to a little under a half of the original range, on average. Of course, four of the inputs are constrained here, which has quite a large impact.
We can see what impacts the constraints have individually
The NBP constraint has no marginal impact
Vegetation carbon (cVeg) has the strongest impact on everything else. This is no suprise, given that so few of the ensemble members seem to simulate carbon vegetation high enough.
Writing robust, parallelised, multistart emulators
LS0tCnRpdGxlOiAiU2Vuc2l0aXZpdHkgYW5hbHlzaXMgYW5kIGNvbnN0cmFpbnQgb2YgdGhlIHBhcmFtZXRlciBzcGFjZSBvZiBFYXJ0aCBTeXN0ZW0gY29uZmlndXJhdGlvbiBvZiBKVUxFUyIKYXV0aG9yOiAiRG91ZyBNY05lYWxsIgpkYXRlOiAiMjQvMDMvMjAyMSIKb3V0cHV0OiAKICAgIGh0bWxfbm90ZWJvb2s6CiAgICAgICAgdG9jOiB0cnVlCiAgICAgICAgdG9jX2Zsb2F0OiB0cnVlCiAgICAgICAgdG9jX2RlcHRoOiAzCiAgICAgICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCi0tLQoKIyBJbnRyb2R1Y3Rpb24KVXBkYXRlIG9mIGV4cGxvcmUtSlVMRVMtRVMtMXAwLlJtZCB0aGF0IHVzZXMgdGhlIG5ldyBwYWNrYWdlcyBhbmQgZnVuY3Rpb25zCgpXZSBidWlsZCBhbmQgdGVzdCBnYXVzc2lhbiBwcm9jZXNzIGVtdWxhdG9ycywgcGVyZm9ybSBhIHNlbnNpdGl2aXR5IGFuYWx5aXMsIGFuZCBjb25zdHJhaW4gdGhlIGlucHV0IHNwYWNlIG9mIEp1bGVzLgoKCkFuZHkgdGhpbmtzIHRoZXJlIG1pZ2h0IGJlIG1pbGVhZ2UgaW4gYW5hbHlzaW5nIHRoZSBhdG1vc3BoZXJpYyBncm93dGgsIHdoaWNoIGlzIGhlcmUuCi9ob21lL2gwMS9oYWRhdy9SZXNlYXJjaC9FU19QUEUvT2N0MjAKICAKQXQgdGhlIG1vbWVudCwgdGhpcyB2aWduZXR0ZSBpcyBoYW1wZXJlZCBieSB0aGUgZmFjdCB0aGF0IGVtdWxhdG9ycyBhcmUgZmFpbGluZyBvbiBhIGZldyBvZiB0aGUgb3V0cHV0cyB3aGljaCByZXByZXNlbnQgY2hhbmdlIG92ZXIgdGhlIGhpc3RvcmljYWwgcGVyaW9kLiBUaGUgZW11bGF0b3IgaXMgZmluZSBmb3IgcHJlZGljdGluZyBhYnNvbHV0ZSB2YWx1ZXMgaW4gdGhlIG1vZGVybiBwZXJpb2QuCgpBbmR5IHdvdWxkIGxpa2UgdG8gc2VlIHRpbWVzZXJpZXMgb2Y6CmNWZWcsIGNTb2lsIGFuZCBuYnAsIG5wcCBpbiBHdEMgYW5kIEd0Qy95ci4KCiMjIFByZWxpbWluYXJpZXMKTG9hZCBsaWJyYXJpZXMsIGZ1bmN0aW9ucyBhbmQgZGF0YS4KCmBgYHtyLCBlY2hvID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cyA9ICdoaWRlJ30KIyBMb2FkIGhlbHBlciBmdW5jdGlvbnMKCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcucGF0aCA9ICJmaWdzLyIsIGVjaG8gPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5ncyA9IEZBTFNFKQoKIyBsb2FkIGhlbHBlciBmdW5jdGlvbnMsIGRhdGEgYW5kIGRvIHByZWxpbWluYXJ5IHByb2Nlc3Npbmcgb2YgdGhlIGVuc2VtYmxlLgpzb3VyY2UoJ0pVTEVTLUVTLTFwMC1jb21tb24uUicpCmBgYAoKCgojIyBDYXJib24gYnVkZ2V0IGRhdGEKCltTZWN0aW9uIDIuNSBpbiBGcmllZGxpbmdzdGVpbiBldCBhbC5dKGh0dHBzOi8vZXNzZC5jb3Blcm5pY3VzLm9yZy9hcnRpY2xlcy8xMi8zMjY5LzIwMjAvI3NlY3Rpb24yKSBkZXNjcmliZXMgaG93IHRoZSBsYW5kIGNhcmJvbiBzaW5rIGlzIGVzdGltYXRlZC4KYGBge3IsIGhpc3RvcmljYWwtY2FyYm9uLWJ1ZGdldCwgd2FybmluZyA9IEZBTFNFLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDEwfQoKI3BkZihmaWxlID0gJ2NhcmJvbl9idWRnZXQucGRmJywgd2lkdGggPSAxMCwgaGVpZ2h0ID0gOCkKIyBRdWVzdGlvbjogSG93IGNsb3NlbHkgc2hvdWxkIG91ciBtb2RlbCBtYXRjaCB0aGlzIGN1cnZlPyBXaGljaCBvdXRwdXQ/CiMgKE15IGd1ZXNzIGlzICdUb3RhbCBMYW5kIENhcmJvbiBhbm9tYWx5JykKaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0IDwtIHJlYWRfZXhjZWwoJ0dsb2JhbF9DYXJib25fQnVkZ2V0XzIwMjB2MS4wLnhsc3gnLCBzaGVldCA9ICJIaXN0b3JpY2FsIEJ1ZGdldCIsIHNraXAgPSAxNSwgbl9tYXggPSAyNzApCgpwYXIobWZyb3cgPSBjKDMsMikpCnlsaW0gPSBjKC0xLCA2KQoKCmxhbmRfc2lua19uZXQgPC0gaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBsYW5kIHNpbmtgIC0gaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBsYW5kLXVzZSBjaGFuZ2UgZW1pc3Npb25zYAoKcGxvdChoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciwgaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBmb3NzaWwgZW1pc3Npb25zIGV4Y2x1ZGluZyBjYXJib25hdGlvbmAsIG1haW4gPSAnZm9zc2lsIGVtaXNzaW9ucyBleGNsdWRpbmcgY2FyYm9uYXRpb24nLCB5bGFiID0gJycsCiAgICAgdHlwZSA9ICdsJywgYnR5ID0gJ24nLCB5bGltID0geWxpbSkKCnBsb3QoaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JFllYXIsIGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRgbGFuZCBzaW5rYCwgbWFpbiA9ICdsYW5kIHNpbmsnLCB5bGFiID0gJycsIHR5cGUgPSAnbCcsIGJ0eSA9ICduJywgeWxpbSA9IHlsaW0pCgpsaW5lcyhoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciwgbGFuZF9zaW5rX25ldCwgY29sID0gJ3JlZCcpCgpsZWdlbmQoJ3RvcGxlZnQnLCBsZWdlbmQgPSAnbGFuZCBzaW5rIC0gbGFuZCB1c2UgY2hhbmdlIGVtaXNzaW9ucycsIGNvbCA9ICdyZWQnLCBsdHkgPSAnc29saWQnKQoKcGxvdChoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciwgaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBsYW5kLXVzZSBjaGFuZ2UgZW1pc3Npb25zYCwgbWFpbiA9ICdsYW5kIHVzZSBjaGFuZ2UgZW1pc3Npb25zJywKICAgICB5bGFiID0gJycsIHR5cGUgPSAnbCcsIGJ0eSA9ICduJywgeWxpbSA9IHlsaW0pCgpwbG90KGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyLCBoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkYGF0bW9zcGhlcmljIGdyb3d0aGAsIG1haW4gPSAnYXRtb3NwaGVyaWMgZ3Jvd3RoJywgeWxhYiA9ICcnLAogICAgIHR5cGUgPSAnbCcsIGJ0eSA9ICduJywgeWxpbSA9IHlsaW0pCgoKcGxvdChoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciwgaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBvY2VhbiBzaW5rYCwgbWFpbiA9ICdvY2VhbiBzaW5rJywgdHlwZSA9ICdsJywgYnR5ID0gJ24nLCB5bGltID0geWxpbSkKCnBsb3QoaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JFllYXIsIGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRgYnVkZ2V0IGltYmFsYW5jZWAsIG1haW4gPSAnYnVkZ2V0IGltYmFsYW5jZScsIHlsYWIgPSAnJywgdHlwZSA9ICdsJywgYnR5ID0gJ24nLCB5bGltID0geWxpbSkKCiNkZXYub2ZmKCkKYGBgCgoKIyMjIFZhcmlhYmxlcyBhdmFpbGFibGUgZm9yIGFuYWx5c2lzCgpMb2FkIGEgc2luZ2xlIGVuc2VtYmxlIG1lbWJlciB0byBleGFtaW5lIGNvbnRlbnRzCmBgYHtyLCBsb2FkLW91dHB1dC1lbnNlbWJsZX0KZW5zbWVtYmVyIDwtICdQMDAwMC8nCnN1YmRpciA8LSAnc3RhdHMvJwoKZmxvYyA8LSBwYXN0ZTAoZW5zbG9jLGVuc21lbWJlcixzdWJkaXIpCmZuIDwtICdKVUxFUy1FUy0xcDBfUDAwMDBfQW5udWFsX2dsb2JhbC5uYycKCiMgdGVzdCBmaWxlCm5jIDwtIG5jX29wZW4ocGFzdGUwKGZsb2MsZm4pKQoKIyBXaGF0IHZhcmlhYmxlcyBhcmUgaW4gdGhlIGZpbGU/IAp2YXJsaXN0IDwtIG5jLmdldC52YXJpYWJsZS5saXN0KG5jKQoKZm9yKGkgaW4gMTpsZW5ndGgodmFybGlzdCkpewogIAogIHZhciA8LSB2YXJsaXN0W2ldCiAgcHJpbnQodmFyKQogIHByaW50KG5jYXR0X2dldChuYyx2YXIsImxvbmdfbmFtZSIpW1syXV0pCn0KYGBgCgoKIyMgUGxvdCB0aW1lc2VyaWVzIG9mIGFnZ3JlZ2F0ZWQgZ2xvYmFsIHRpbWVzZXJpZXMgCgoKYGBge3IgcGxvdC1jYXJib24tY3ljbGUtdGltZXNlcmllcy1wcmltYXJ5LCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDEyfQoKI3BkZihmaWxlID0gJ2ZpZ3MvcGxvdC1jYXJib24tY3ljbGUtdGltZXNlcmllcy1wcmltYXJ5LTEucGRmJywgd2lkdGggPSAxMCwgaGVpZ2h0ID0gMTIpCnBhcihtZnJvdz0gYygzLDQpLCBsYXMgPSAxKQoKcGxvdGNvbCA8LSBjKG1ha2VUcmFuc3BhcmVudCgnYmxhY2snLCA3MCkpCgp5bGltID0gcmFuZ2UoYyhucHBfZW5zWywxXSwgbnBwX2Vuc1ssMTY0XSkpCm1hdHBsb3QoeWVhcnMsIHQobnBwX2VucyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdHdEMnLCBtYWluID0gJ05QUCcsIHhsYWIgPSAnJywKICAgICAgICBidHkgPSAnbicpCgp5bGltID0gcmFuZ2UoYyhjU29pbF9lbnNbLDFdLCBjU29pbF9lbnNbLDE2NF0pKQptYXRwbG90KHllYXJzLCB0KGNTb2lsX2VucyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdHdEMnLCBtYWluID0gJ1NvaWwgQ2FyYm9uJyx4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKGMoY1ZlZ19lbnNbLDFdLCBjVmVnX2Vuc1ssMTY0XSkpCm1hdHBsb3QoeWVhcnMsIHQoY1ZlZ19lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdWZWdldGF0aW9uIENhcmJvbicseGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSByYW5nZSh0b3RhbF9sYW5kX2NhcmJvbl9lbnMpCm1hdHBsb3QoeWVhcnMsIHQodG90YWxfbGFuZF9jYXJib25fZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwgCiAgICAgICAgeWxhYiA9ICdHdEMnLCBtYWluID0gJ1RvdGFsIExhbmQgQ2FyYm9uJyx4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQoKCnlsaW0gPSByYW5nZShsYWlfbG5kX21lYW5fZW5zKQptYXRwbG90KHllYXJzLCB0KGxhaV9sbmRfbWVhbl9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnTEFJJywgbWFpbiA9ICdMZWFmIGFyZWEgaW5kZXgnLHhsYWIgPSAnJywKICAgICAgICBidHkgPSAnbicpCgp5bGltID0gcmFuZ2UodHJlZUZyYWNfbG5kX21lYW5fZW5zKQptYXRwbG90KHllYXJzLCB0KHRyZWVGcmFjX2xuZF9tZWFuX2VucyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdmcmFjdGlvbicsIG1haW4gPSAnVHJlZSBmcmFjdGlvbicseGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSByYW5nZShzaHJ1YkZyYWNfbG5kX21lYW5fZW5zKQptYXRwbG90KHllYXJzLCB0KHNocnViRnJhY19sbmRfbWVhbl9lbnMgKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ2ZyYWN0aW9uJywgbWFpbiA9ICdTaHJ1YiBmcmFjdGlvbicseGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSBjKDAsMTAwKQptYXRwbG90KHllYXJzLCB0KGJhcmVzb2lsRnJhY19sbmRfbWVhbl9lbnMgKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ2ZyYWN0aW9uJywgbWFpbiA9ICdiYXJlIHNvaWwgZnJhY3Rpb24nLHhsYWIgPSAnJywKICAgICAgICBidHkgPSAnbicpCgp5bGltID0gYygtMTAsIDEwKQptYXRwbG90KHllYXJzLCB0KG5icF9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLCAKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnTkJQJywgeGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKICAKeWxpbSA9IHJhbmdlKHJoX2xuZF9zdW1fZW5zKQptYXRwbG90KHllYXJzLCB0KHJoX2xuZF9zdW1fZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0Qy95ZWFyJywgbWFpbiA9ICdIZXRlcm90cm9waGljIFJlc3BpcmF0aW9uJywgeGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSByYW5nZShmTHVjX2xuZF9zdW1fZW5zKQptYXRwbG90KHllYXJzLCB0KGZMdWNfbG5kX3N1bV9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDL3llYXInLCBtYWluID0gJ0xhbmQgdXNlIGNoYW5nZSBlbWlzc2lvbnMnLCB4bGFiID0gJycsCiAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKGZIYXJ2ZXN0X2xuZF9zdW1fZW5zKQptYXRwbG90KHllYXJzLCB0KGZIYXJ2ZXN0X2xuZF9zdW1fZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0Qy95ZWFyJywgbWFpbiA9ICdIYXJ2ZXN0IEMgZmx1eCB0byBhdG1vc3BoZXJlJywgeGxhYiA9ICcnLAogICAgICAgIGJ0eSA9ICduJykKCiNkZXYub2ZmKCkKCmBgYAoKCmBgYHtyIHBsb3QtY2FyYm9uLWN5Y2xlLWFub21hbHktdGltZXNlcmllcywgZmlnLndpZHRoID0gOSwgZmlnLmhlaWdodCA9IDZ9CgpwYXIobWZyb3c9IGMoMSw0KSwgbGFzID0gMSkKCiMgeWxpbSA9IHJhbmdlKC0xMCwgMTApCiNtYXRwbG90KHllYXJzLCB0KG5icF9lbnNfYW5vbSksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiMgICAgICAgIHlsYWIgPSAnTkJQIHN1bSBBbm9tYWx5JywgbWFpbiA9ICdOQlAgQW5vbWFseScsCiMgICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSByYW5nZShjKG5wcF9lbnNfYW5vbVssMV0sIG5wcF9lbnNfYW5vbVssMTY0XSkpCm1hdHBsb3QoeWVhcnMsIHQobnBwX2Vuc19hbm9tKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ05QUCBzdW0gQW5vbWFseScsIG1haW4gPSAnTlBQIEFub21hbHknLAogICAgICAgIGJ0eSA9ICduJykKCnlsaW0gPSByYW5nZShjKGNTb2lsX2Vuc19hbm9tWywxXSwgY1NvaWxfZW5zX2Fub21bLDE2NF0pKQptYXRwbG90KHllYXJzLCB0KGNTb2lsX2Vuc19hbm9tKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnU29pbCBDYXJib24gQW5vbWFseScsCiAgICAgICAgYnR5ID0gJ24nKQoKeWxpbSA9IHJhbmdlKGMoY1ZlZ19lbnNfYW5vbVssMV0sIGNWZWdfZW5zX2Fub21bLDE2NF0pKQptYXRwbG90KHllYXJzLCB0KGNWZWdfZW5zX2Fub20pLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdWZWdldGF0aW9uIENhcmJvbiBBbm9tYWx5JywKICAgICAgICBidHkgPSAnbicpCgp5bGltID0gcmFuZ2UodG90YWxfbGFuZF9jYXJib25fYW5vbSkKbWF0cGxvdCh5ZWFycywgdCh0b3RhbF9sYW5kX2NhcmJvbl9hbm9tKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnVG90YWwgTGFuZCBDYXJib24gQW5vbWFseScsCiAgICAgICAgYnR5ID0gJ24nKQoKCmBgYAoKCgojIyBXaGVyZSBkaWQgdGhlIG1vZGVsIGZhaWwgdG8gcnVuPwooInByb2JhYmlsaXR5IG9mIHJ1biBmYWlsdXJlIiBDb3VsZCBiZSBhbiBpbnRlcmVzdGluZyBwcm9qZWN0IC0gbG9naXQgdHJhbnNmb3JtYXRpb24gZm9yIHByb2JhYmlsaXR5IG9mIHJ1biBmYWlsdXJlPyBTb21lIG90aGVyIE1MIGxpa2UgU1ZNPwoKVGhlcmUgYXJlIGNsZWFyIHJ1biBmYWlsdXJlIHRocmVzaG9sZHMgaW4gdGhlIHBhcmFtZXRlcnMgcm9vdGRfZnRfaW8gYW5kIGxhaV9tYXgsIGFuZCBxdWl0ZSBzdHJvbmcgdmlzdWFsIGluZGljYXRpb25zIHRoYXQgYV93bF9pbyBhbmQgYmlvX2h1bV9jbiBtYXR0ZXIuCgoKTkVYVCwgaGlzdG9ncmFtcyBvZiBmYWlsdXJlIHdpdGggdGhlIExIUyB2YWx1ZQpgYGB7ciBydW4tZmFpbHVyZS1wYWlycywgZmlnLndpZHRoID0gMTEsIGZpZy5oZWlnaHQgPSAxMX0KCiMgTkIsIHBsb3R0aW5nIHRoZSBpbnZlcnNlIG9mIHRoaXMgZG9lc24ndCBnaXZlIHlvdSBtdWNoIGluZm9ybWF0aW9uCiNwZGYoZmlsZSA9ICdmaWdzL3J1bi1mYWlsdXJlLXBhaXJzLnBkZicsIHdpZHRoID0gMTEsIGhlaWdodCA9IDExKQojc2ltcGxlIHdheQojcGFyKHhwZCA9IFRSVUUpCnBhaXJzKFhfbmxldmVsMCwgCiAgICAgIHhsaW0gPSBjKDAsMSksIHlsaW0gPSBjKDAsMSksCiAgICAgIGxhYmVscyA9IDE6ZCwKICAgICAgY29sID0gbWFrZVRyYW5zcGFyZW50KCdyZWQnLCAxNTApLAogICAgICBnYXAgPSAwLAogICAgICBwY2ggPSAyMCwKICAgICAgeGF4dCA9J24nLCB5YXh0ID0gJ24nLAogICAgICBsb3dlci5wYW5lbCA9IE5VTEwsCiAgICAgIG9tYSA9IGMoMC41LCAwLjUsIDAuNSwgMC41KSkKCnJlc2V0KCkKCmxlZ2VuZCgnbGVmdCcsIGxlZ2VuZCA9IHBhc3RlKDE6ZCwgY29sbmFtZXMobGhzKSksIGNleCA9IDEuMiwgYnR5ID0gJ24nKQoKI2Rldi5vZmYoKQoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gOH0KCiNwZGYoZmlsZSA9ICdmaWdzL3J1bi1mYWlsdXJlLWhpc3RzLnBkZicsIHdpZHRoID0gMTIsIGhlaWdodCA9IDgpCgpwYXIobWZyb3cgPSBjKDQsIDgpLCBtYXIgPSBjKDQsMywyLDEpKQoKZm9yKGkgaW4gMTpkKXsKICAKICBoaXN0KFhfbmxldmVsMFssaV0sIHhsaW0gPSBjKDAsMSksIGJyZWFrcyA9IHNlcShmcm9tPTAsIHRvID0gMSwgYnkgPSAwLjEpLCBjb2wgPSAnZ3JleScsIG1haW4gPSAnJywgeWxpbSA9IGMoMCw5KSwKICAgICAgIGJvcmRlciA9ICd3aGl0ZScsIHhsYWIgPSBjb2xuYW1lcyhYX25sZXZlbDApW2ldLCB5bGFiID0gJycsIGxhcyA9IDEsIGNleC5sYWIgPSAxLjUpCn0KCiNkZXYub2ZmKCkKCmBgYAoKQ291bGQgdHJ5IGFuIFNWTSwgbG9naXN0aWMgcmVncmVzc2lvbiBvciBzaW1pbGFyLgoKCiMjIFRlc3RpbmcgR2F1c3NpYW4gUHJvY2VzcyBlbXVsYXRvcnMKCgojIyMgTlBQIGFzIGEgdGVzdApGaXJzdCwgdXNlIG1lYW4gTlBQIGFzIGFuIGV4YW1wbGUuIEhvdyBkb2VzIE5QUCByZXNwb25kIHRvIGVhY2ggcGFyYW1ldGVyPyBOQXMgYXJlIHJlbW92ZWQsIGJ1dCB6ZXJvIHZhbHVlcyBhcmUgc3RpbGwgaW5jbHVkZWQuCgpgYGB7ciBwbG90LW5wcC1tb2Rlcm4sIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gMTJ9CnAgPC0gbmNvbChYX2xldmVsMCkKCnlfbGV2ZWwwIDwtIFlfbGV2ZWwwWywnbnBwX25saW1fbG5kX3N1bSddCgpwYXIobWZyb3cgPSBjKDUsNyksIG1hciA9IGMoMywxLDMsMSksIG9tYSA9IGMoMSwxLDUsMSkpCmZvcihpIGluIDE6cCl7CiAgcGxvdChYX2xldmVsMFssaV0sIHlfbGV2ZWwwLCB4bGFiID0gJycsIHlsYWIgPSAnJywgbWFpbiA9IGNvbG5hbWVzKFhfbGV2ZWwwKVtpXSkKfQptdGV4dCgnTlBQJywgb3V0ZXIgPSBUUlVFLCBzaWRlID0gMywgY2V4ID0gMiwgbGluZSA9IDIpCgpgYGAKCgpgYGB7ciBwbG90LW5wcC1jaGFuZ2UsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gMTJ9Cgp5YW5vbV9sZXZlbDAgPC0gWUFub21fbGV2ZWwwWywnbnBwX25saW1fbG5kX3N1bSddCgpwYXIobWZyb3cgPSBjKDUsNyksIG1hciA9IGMoMywxLDMsMSksIG9tYSA9IGMoMSwxLDUsMSkpCmZvcihpIGluIDE6cCl7CiAgcGxvdChYX2xldmVsMFssaV0sIHlhbm9tX2xldmVsMCwgeGxhYiA9ICcnLCB5bGFiID0gJycsIG1haW4gPSBjb2xuYW1lcyhYX2xldmVsMClbaV0pCn0KbXRleHQoJ05QUCBjaGFuZ2Ugb3ZlciB0aW1lJywgb3V0ZXIgPSBUUlVFLCBzaWRlID0gMywgY2V4ID0gMiwgbGluZSA9IDIpCgpgYGAKCgojIyBSZWxhdGlvbnNoaXAgYmV0d2VlbiBtb2Rlcm4gTlBQIGFuZCBjaGFuZ2Ugc2luY2UgMTg1MC4KClNvbWUgb3V0cHV0cyAoZS5nIGZMdWMsIGZIYXJ2ZXN0KSBoYXZlIGFuIGFsbW9zdCBwZXJmZWN0IDE6MSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtb2Rlcm4gdmFsdWUgYW5kIGNoYW5nZSwgc29tZSAgKG5icCwgbnBwLCB0cmVlRnJhYykgcXVpdGUgb3IgbW9kZXJhdGVseSBzdHJvbmcsIGFuZCBzb21lIChjc29pbCwgY3ZlZykgdmVyeSB3ZWFrIG9yIG5vbi1leGlzdGFudC4KYGBge3IgbnBwLW1vZGVybi12cy1jaGFuZ2UsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gOH0KCnBhcihtZnJvdyA9IGMoNCw3KSwgbWFyID0gYygzLDEsMywxKSwgb21hID0gYyg0LDUsMSwxKSkKCnBkYXNoIDwtIG5jb2woWV9sZXZlbDApCgpmb3IoaSBpbiAxOnBkYXNoKXsKICAKICB5X2xldmVsMCA8LSBZX2xldmVsMFssaV0KICB5YW5vbV9sZXZlbDAgPC0gWUFub21fbGV2ZWwwWyxpXQogIAogIHBsb3QoeV9sZXZlbDAsIHlhbm9tX2xldmVsMCwgeGxhYiA9ICcnLCB5bGFiID0gJycsIG1haW4gPSBjb2xuYW1lcyhZX2xldmVsMClbaV0pCn0KCm10ZXh0KHRleHQgPSAnTW9kZXJuIHZhbHVlJywgc2lkZSA9IDEsIGxpbmUgPSAyLCBvdXRlciA9IFRSVUUsIGNleCA9IDIpCm10ZXh0KHRleHQgPSAnQ2hhbmdlJywgc2lkZSA9IDIsIGxpbmUgPSAyLCBvdXRlciA9IFRSVUUsIGNleCA9IDIpCgpgYGAKCgoKIyMgQSBjbGVhciB0aHJlc2hvbGQgaW4gdGhlIEYwIHBhcmFtZXRlciBmb3IgTlBQCkl0IGFwcGVhcnMgdGhhdCB0aGlzIGVuc2VtYmxlIGlzIGxlc3MgImNsZWFyIGN1dCIgaW4gaGF2aW5nIGFuIG91dHB1dCB0aGF0IGNsZWFybHkgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuICJmYWlsZWQiIChvciBjbG9zZSB0byBpdCksIGFuZCAibm90IGZhaWxlZCIuCgpIYXZpbmcgc2FpZCB0aGF0LCBoYXZpbmcgYW4gRjAgb3ZlciBhIHRocmVzaG9sZCBzZWVtcyB0byBraWxsIHRoZSBjYXJib24gY3ljbGUsIGFzIGJlZm9yZS4gSGVyZSwgd2UndmUgc2V0IGEgdGhyZXNob2xkIG9mIDAuOSAob24gdGhlIG5vcm1hbGlzZWQgc2NhbGUpIGZvciBGMCwgYW5kIHdlIHJlbW92ZSBtZW1iZXJzIG9mIHRoZSBlbnNlbWJsZSB3aXRoIGEgbGFyZ2VyIEYwIHRoYW4gdGhhdCB3aGVuIHdlIGJ1aWxkIGVtdWxhdG9ycy4KCmBgYHtyLCBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gOH0KCnBhcihtZnJvdyA9IGMoMiwxKSkKcGxvdChsaHMkZjBfaW8sIGRhdG1hdFssICducHBfbmxpbV9sbmRfc3VtJ10sIG1haW4gPSAnTXVsdGlwbGljYXRpb24gZmFjdG9yJywgeGxhYiA9ICdmMF9pbycsIHlsYWIgPSAnTlBQIHN1bScpCnBsb3QoWF9sZXZlbDBbLCdmMF9pbyddLCBZX2xldmVsMFssICducHBfbmxpbV9sbmRfc3VtJ10sIHhsYWIgPSAnZjBfaW8nLCBtYWluID0gJ05vcm1hbGl6ZWQnLCB5bGFiID0gJ05QUCBzdW0nKQphYmxpbmUodiA9IDAuOSkKCmBgYAoKCgoKYGBge3IgZmFpbHVyZS1wYWlycywgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEyLCBmaWcucGF0aD0nZmlncy8nLCBkZXY9YygncG5nJywgJ3BkZicpfQoKCmxvd19ucHBfaXggPC0gd2hpY2goWVssJ25wcF9ubGltX2xuZF9zdW0nXSA8IDFlNSkKIyBjb2RlIGZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjgxODI4NzIvaG93LXRvLXVzZS1kaWZmZXJlbnQtc2V0cy1vZi1kYXRhLWluLWxvd2VyLWFuZC11cHBlci1wYW5lbC1vZi1wYWlycy1mdW5jdGlvbi1pbgoKCiNYIDwtIG1hdHJpeChydW5pZigzMDApLCBuY29sPTMpCiNZIDwtIG1hdHJpeChjKHNvcnQocnVuaWYoMTAwLCAwLCAxMCkpLCAKIyAgICAgICAgICAgICAgc29ydChydW5pZigxMDAsIDAsIDEwKSksIAojICAgICAgICAgICAgICBzb3J0KHJ1bmlmKDEwMCwgMCwgMTApKSksIG5jb2w9MykKCiNwZGYoZmlsZSA9ICdmaWdzL3J1bi1mYWlsdXJlLXBhaXJzLnBkZicsIHdpZHRoID0gMTIsIGhlaWdodCA9IDEwKQp4MSA8LSBYW2xvd19ucHBfaXgsIF0KeDIgPC0gWF9ubGV2ZWwwCgpYWSA8LSByYmluZCh4MSwgeDIpCgoKcGFpcnMoWFksCiAgICAgIGxvd2VyLnBhbmVsPWZ1bmN0aW9uKHgsIHksIC4uLikgewogICAgICAgIFh4IDwtIHhbc2VxX2xlbihucm93KHgxKSldICMgY29ycmVzcG9uZHMgdG8gWCBzdWJzZXQKICAgICAgICBYeSA8LSB5W3NlcV9sZW4obnJvdyh4MSkpXSAjIGNvcnJlc3BvbmRzIHRvIFggc3Vic2V0CiAgICAgICAgI3VzciA8LSBwYXIoInVzciIpOyBvbi5leGl0KHBhcih1c3IpKQogICAgICAgICNwYXIodXNyID0gYyhyYW5nZSh4MVssIC1uY29sKHgxKV0pLCByYW5nZSh4MVssIC0xXSkpKSAjIHNldCB1cCBsaW1pdHMKICAgICAgICBwb2ludHMoWHgsIFh5LCBjb2wgPSB6Ymx1ZSwgcGNoID0gMTksIGNleCA9IDAuOCkKICAgICAgICMgaWYocGFyKCdtZmcnKVsyXSA9PSAxKSBheGlzKDIpICMgaWYgbGVmdCBwbG90LCBhZGQgbGVmdCBheGlzCiAgICAgICAgI2lmKHBhcignbWZnJylbMV0gPT0gbmNvbCh4MSkpIGF4aXMoMSkgIyBpZiBib3R0b20gcGxvdCBhZGQgYm90dG9tIGF4aXMKICAgICAgfSwgCiAgICAgIHVwcGVyLnBhbmVsPWZ1bmN0aW9uKHgsIHksIC4uLikgewogICAgICAgIFl4IDwtIHhbKG5yb3coeDEpICsgMSk6bGVuZ3RoKHgpXSAjIFkgc3Vic2V0CiAgICAgICAgWXkgPC0geVsobnJvdyh4MSkgKyAxKTpsZW5ndGgoeSldICMgWSBzdWJzZXQKICAgICAgICAKICAgICAgICAjY250ciA8LSBvdXRlcihZeCwgWXgsIEZVTj0nKicpICMgYXJiaXRyYXJ5IGZ1bmN0aW9uIGZvciBjb250b3VyCiAgICAgICAjIHVzciA8LSBwYXIoInVzciIpOyBvbi5leGl0KHBhcih1c3IpKQogICAgICAgICNwYXIodXNyID0gYyhyYW5nZSh4MlssIC0xXSksIHJhbmdlKHgyWywgLW5jb2woeDIpXSkpKSAjIHNldCB1cCBsaW1pdHMKICAgICAgICBwb2ludHMoWXgsIFl5LCBjb2wgPSB6cmVkLCBwY2ggPSAxOSwgY2V4ID0gMC44KQogICAgICAgICNjb250b3VyKFl4LCBZeSwgY250ciwgYWRkPVRSVUUpCiAgICAgICAgI2lmKHBhcignbWZnJylbMl0gPT0gbmNvbCh4MikpIGF4aXMoNCkgIyBpZiByaWdodCBwbG90LCBhZGQgcmlnaHQgYXhpcwogICAgICAgICNpZihwYXIoJ21mZycpWzFdID09IDEpIGF4aXMoMykgIyBpZiB0b3AgcGxvdCwgYWRkIHRvcCBheGlzCiAgICAgIH0sIAogICAgICAjdGljaz1GQUxTRSwgIyBzdXBwcmVzcyB0aGUgZGVmYXVsdCB0aWNrIG1hcmtzCiAgICAgICNsaW5lPTEsCiAgICAgIGdhcCA9IDAsCiAgICAgIHhsaW0gPSBjKDAsMSksIHlsaW0gPSBjKDAsMSksCiAgICAgIGxhYmVscyA9IDE6ZCwKICAgICAgb21hID0gYygyLCAxOCwgMiwgMikpICMgbW92ZSB0aGUgZGVmYXVsdCB0aWNrIGxhYmVscyBvZmYgdGhlIHBsb3QgCgpyZXNldCgpCgpsZWdlbmQoJ2xlZnQnLCBsZWdlbmQgPSBwYXN0ZSgxOmQsIGNvbG5hbWVzKGxocykpLCBjZXggPSAxLjEsIGJ0eSA9ICduJykKbGVnZW5kKCd0b3BsZWZ0JywgcGNoID0gMTksIGNvbCA9IGMoIHpyZWQsIHpibHVlKSwgbGVnZW5kID0gYygnZmFpbGVkJywgJ3plcm8gY2FyYm9uIGN5Y2xlJyksIGJ0eSA9ICduJywgaW5zZXQgPSAwLjAyLCBjZXggPSAxLjEgKQoKI2Rldi5vZmYoKQoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gOH0KCiNwZGYoZmlsZSA9ICdmaWdzL3J1bi1mYWlsdXJlLWhpc3RzLnBkZicsIHdpZHRoID0gMTIsIGhlaWdodCA9IDgpCgpwYXIobWZyb3cgPSBjKDQsOCksIG1hciA9IGMoNSwzLDIsMSkpCgpmb3IoaSBpbiAxOmQpewogIAogIGhpc3QoeDFbLGldLCB4bGltID0gYygwLDEpLCBicmVha3MgPSBzZXEoZnJvbT0wLCB0byA9IDEsIGJ5ID0gMC4xKSwgY29sID0gemJsdWUsIG1haW4gPSAnJywgeWxpbSA9IGMoMCw1MCksCiAgICAgICBib3JkZXIgPSAnd2hpdGUnLCB4bGFiID0gY29sbmFtZXMoWF9ubGV2ZWwwKVtpXSwgeWxhYiA9ICcnLCBsYXMgPSAxLCBjZXgubGFiID0gMS41KQogIAogIGhpc3QoeDJbLGldLCBicmVha3MgPSBzZXEoZnJvbT0wLCB0byA9IDEsIGJ5ID0gMC4xKSwgY29sID0genJlZCwgYm9yZGVyID0gJ3doaXRlJywgYWRkID0gVFJVRSkKfQoKICAgCiNkZXYub2ZmKCkKCmBgYAoKCiMjIExldmVsIDEgY29uc3RyYWludCAtIHJlbW92ZSBlbnNlbWJsZSBtZW1iZXJzIHdpdGggRjAgYWJvdmUgdGhyZXNob2xkClRoZSBsZXZlbCAxIGNvbnN0cmFpbnQgcmVtb3ZlcyBhbnkgaW5wdXQgd2l0aCBGMCBncmVhdGVyIHRoYW4gMC45IChub3JtYWxpc2VkKSwgd2hpY2ggcmVtb3ZlcyBtYW55IG9mIHRoZSB6ZXJvLWNhcmJvbi1jeWNsZSBtZW1iZXJzIHVwIGZyb250LiBUaGVyZSBhcmUgNDI0IGVuc21ibGUgbWVtYmVycyByZW1haW5pbmcuCgpUaGlzIGRvZXMgY29uc3RyYWludCBzZXF1ZW50aWFsbHksIHdoaWNoIG1heSBub3QgYmUgYSBnb29kIGlkZWEuIApgYGB7cn0KbGV2ZWwxX2l4IDwtIHdoaWNoKFhfbGV2ZWwwWywgJ2YwX2lvJ10gPCAwLjkpCgpYX2xldmVsMSA8LSBYX2xldmVsMFtsZXZlbDFfaXgsIF0KWV9sZXZlbDEgPC0gWV9sZXZlbDBbbGV2ZWwxX2l4LCBdCgpZQW5vbV9sZXZlbDEgPC0gWUFub21fbGV2ZWwwW2xldmVsMV9peCwgXQoKeV9sZXZlbDEgPC0gWV9sZXZlbDFbLCAnbnBwX25saW1fbG5kX3N1bSddCmBgYAoKIyMjIENvbXBhcmlzb24gb2YgbGV2ZWwgMCBhbmQgbGV2ZWwgMSBlbXVsYXRvcnMgZm9yIE5QUCAobW9kZXJuIHZhbHVlKQoKYGBge3IsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA3LCByZXN1bHRzID0gJ2hpZGUnLCB3YXJuaW5nPUZBTFNFfQplbV9ucHBfbGV2ZWwwIDwtIGttKH4uLCBkZXNpZ24gPSBYX2xldmVsMCwgIHJlc3BvbnNlID0geV9sZXZlbDApCmVtX25wcF9sZXZlbDEgPC0ga20ofi4sIGRlc2lnbiA9IFhfbGV2ZWwxLCAgcmVzcG9uc2UgPSB5X2xldmVsMSkKCmVtX25wcF9sZXZlbDBfbXMgPC0ga20ofi4sIGRlc2lnbiA9IFhfbGV2ZWwwLCAgcmVzcG9uc2UgPSB5X2xldmVsMCwgbXVsdGlzdGFydCA9IDQpCmVtX25wcF9sZXZlbDFfbXMgPC0ga20ofi4sIGRlc2lnbiA9IFhfbGV2ZWwxLCAgcmVzcG9uc2UgPSB5X2xldmVsMSwgbXVsdGlzdGFydCA9IDQpCgoKYGBgCgoKICMgUGxvdCB0aGUgcmVndWxhciBrbSBlbXVsYXRvci4gRG9lc24ndCBsb29rIGdyZWF0LgoKYGBge3IgcGxvdC1lbS1ucHAtbGV2ZWwwLCBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gN30KcGxvdChlbV9ucHBfbGV2ZWwwKQpgYGAKCmBgYHtyIHBsb3QtZW0tbnBwLWxldmVsMSwgZmlnLndpZHRoID0gNywgZmlnLmhlaWdodCA9IDd9CnBsb3QoZW1fbnBwX2xldmVsMSkKYGBgCgoKIyMjIExlYXZlLW9uZS1vdXQgc3VtbWFyaWVzIG9mIE5QUCBlbXVsYXRvcnMKYGBge3J9Cgpsb29fbnBwX2xldmVsMCA8LSBsZWF2ZU9uZU91dC5rbShlbV9ucHBfbGV2ZWwwLCB0eXBlID0gJ1VLJywgdHJlbmQucmVlc3RpbSA9IFRSVUUpCmxvb19ucHBfbGV2ZWwxIDwtIGxlYXZlT25lT3V0LmttKGVtX25wcF9sZXZlbDEsIHR5cGUgPSAnVUsnLCB0cmVuZC5yZWVzdGltID0gVFJVRSkKClJNU0UgKCBsb29fbnBwX2xldmVsMCRtZWFuLCB5X2xldmVsMCkKUk1TRSAoIGxvb19ucHBfbGV2ZWwxJG1lYW4sIHlfbGV2ZWwxKQoKCiMgSG93IGFib3V0IE1BRSBvdmVyIHRoZSByYW5nZQpwcm9wX21hZSA8LSBmdW5jdGlvbihZLCBZcHJlZCl7CiAgIyBtZWFuIGFic29sdXRlIGVycm9yIGFzIGEgcHJvcG9ydGlvbiBvZiB0aGUgcmFuZ2Ugb2Ygb3V0cHV0CiAgCiAgYWJzZGlmZiA8LSBhYnMoZGlmZihyYW5nZShZKSkpCiAgCiAgbWFlIDwtIE1BRShZLCBZcHJlZCkKICAKICBwcm9wbWFlIDwtIChtYWUgLyBhYnNkaWZmKSAqIDEwMAogIAogIHByb3BtYWUKICAKfQoKcHJvcF9tYWUoeV9sZXZlbDAsIGxvb19ucHBfbGV2ZWwwJG1lYW4pCgpwcm9wX21hZSh5X2xldmVsMSwgbG9vX25wcF9sZXZlbDEkbWVhbikKCgoKCgoKYGBgCgoKYGBge3J9CgoKCgpgYGAKCmBgYHtyfQoKIyBNT1ZFIFRISVMgVE8gSU1QVE9PTFMgT1IgRU1UT09MUwojIEdpdmVuIGEga20gbW9kZWwsIHByb2R1Y2Ugc29tZSBlcnJvciBzdGF0aXN0aWNzCgoKYGBgCgpgYGB7cn0KCiMgSXQgZG9lc24ndCBsb29rIGxpa2UgTXVsdGlzdGFydCBtYWtlcyBhIGJpZyBkaWZmZXJlbmNlIGF0IGFsbCBmb3IgTlBQCmVycnN0YXRzX25wcF9sZXZlbDAgPC0ga21Mb29TdGF0cyhrbSA9IGVtX25wcF9sZXZlbDApCmVycnN0YXRzX25wcF9sZXZlbDBfbXMgPC0ga21Mb29TdGF0cyhrbSA9IGVtX25wcF9sZXZlbDBfbXMpCgplcnJzdGF0c19ucHBfbGV2ZWwxIDwtIGttTG9vU3RhdHMoa20gPSBlbV9ucHBfbGV2ZWwxKQplcnJzdGF0c19ucHBfbGV2ZWwxX21zIDwtIGttTG9vU3RhdHMoa20gPSBlbV9ucHBfbGV2ZWwxX21zKQoKCiMgcHJvcG9ydGlvbmFsIG1lYW4gYWJzb2x1dGUgZXJyb3IKZXJyc3RhdHNfbnBwX2xldmVsMCRwbWFlCmVycnN0YXRzX25wcF9sZXZlbDBfbXMkcG1hZQoKCmVycnN0YXRzX25wcF9sZXZlbDEkcG1hZQplcnJzdGF0c19ucHBfbGV2ZWwxX21zJHBtYWUKCgoKCmBgYAoKCgoKCmBgYHtyfQojIERpY2VFdmFsIGlzIHVzZWZ1bCBidXQgc2xvdy9hd2t3YXJkCgojIERFX2VtX25wcF9sZXZlbDAgPC0gbW9kZWxGaXQoWCA9IFhfbGV2ZWwwLCBZID0geV9sZXZlbDAsIHR5cGUgPSAnS3JpZ2luZycsIGZvcm11bGEgPSB+LiApCiMgREVfZW1fbnBwX2xldmVsMSA8LSBtb2RlbEZpdChYID0gWF9sZXZlbDEsIFkgPSB5X2xldmVsMSwgdHlwZSA9ICdLcmlnaW5nJywgZm9ybXVsYSA9IH4uICkKCiMgbnBwX2VtX2N2X2xldmVsMCA8LSBjcm9zc1ZhbGlkYXRpb24oREVfZW1fbnBwX2xldmVsMCwgNSkKIyBucHBfZW1fY3ZfbGV2ZWwxICA8LSBjcm9zc1ZhbGlkYXRpb24oREVfZW1fbnBwX2xldmVsMSwgNSkKCmBgYAoKCgojIyBDb25zdHJhaW4gZmlyc3QgYW5kIHRoZW4gZG8gc2Vuc2l0aXZpdHkgYW5hbHlzaXM/ClRoZSBwcm9ibGVtIHdpdGggZG9pbmcgY29uc3RyYWludCBmaXJzdCBpcyB0aGF0IHlvdSBlbmQgdXAgd2l0aCBhIG5vbi1oeXBlcmN1YmUgc2hhcGVkIGlucHV0IHNwYWNlIChjb3JuZXJzIGhhdmUgYmVlbiBrbm9ja2VkIG9mZiBieSBjb25zdHJhaW50KSwgd2hpY2ggaXMgbm90IGlkZWFsLiBXZSBtaWdodCB0aGVyZWZvcmUgd2FudCBkaWZmZXJlbnQgc2Vuc2l0aXZpdHkgbWVhc3VyZXMgZm9yIHByZS0gYW5kIHBvc3QtY29uc3RyYWluZWQgZW5zZW1ibGUuCgoKYGBge3J9Cgojc2Vuc3ZhciBuZWVkcyB0byBnbyBpbnRvIGVtdG9vbHMgd2l0aCBvYWF0X2Rlc2lnbgpzZW5zdmFyIDwtIGZ1bmN0aW9uKG9hYXRfcHJlZCwgbiwgZCl7CiAgIyBDYWxjdWxhdGUgdmFyaWFuY2UgYXMgYSBnbG9iYWwgc2Vuc2l0aXZpdHkgbWVhbnN1cmUKICBvdXQgPSByZXAoTkEsZCkKICBmb3IoaSBpbiAxOmQpewogICAgaXggPSBzZXEoZnJvbSA9ICgoaSpuKSAtIChuLTEpKSwgdG8gPSAgKGkqbiksIGJ5ID0gMSkKICAgIG91dFtpXSA9IHZhcihvYWF0X3ByZWQkbWVhbltpeF0pCiAgfQogIG91dAp9CgoKYGBgCgoKYGBge3J9CnR3b1N0ZXBfZ2xtbmV0IDwtIGZ1bmN0aW9uKFgsIHksIG51Z2dldD1OVUxMLCBudWdnZXRFc3RpbT1GQUxTRSwgbm9pc2VWYXI9TlVMTCwgc2VlZD1OVUxMLCB0cmFjZT1GQUxTRSwgbWF4aXQ9MTAwLAogICAgICAgICAgICAgICAgICAgICAgICAgIFJFUE9SVD0xMCwgZmFjdHI9MWU3LCBwZ3RvbD0wLjAsIHBhcmluaXQ9TlVMTCwgcG9wc2l6ZT0xMDApewogICMgVXNlIGxhc3NvIHRvIHJlZHVjZSBpbnB1dCBkaW1lbnNpb24gb2YgZW11bGF0b3IgYmVmb3JlCiAgIyBidWlsZGluZy4KICBjb250cm9sX2xpc3QgPSBsaXN0KHRyYWNlPXRyYWNlLCBtYXhpdD1tYXhpdCwgUkVQT1JUPVJFUE9SVCwgZmFjdHI9ZmFjdHIsIHBndG9sPXBndG9sLCBwb3Auc2l6ZT1wb3BzaXplKQogIHh2YXJzID0gY29sbmFtZXMoWCkKICBkYXRhID0gZGF0YS5mcmFtZShyZXNwb25zZT15LCB4PVgpCiAgY29sbmFtZXMoZGF0YSkgPC0gYygicmVzcG9uc2UiLCB4dmFycykKICBudmFsID0gbGVuZ3RoKHkpCiAgCiAgIyBmaXQgYSBsYXNzbyBieSBjcm9zcyB2YWxpZGF0aW9uCiAgbGlicmFyeShnbG1uZXQpCiAgZml0X2dsbW5ldF9jdiA9IGN2LmdsbW5ldCh4PVgseT15KQogIAogICMgVGhlIGxhYmVscyBvZiB0aGUgcmV0YWluZWQgY29lZmZpY2llbnRzIGFyZSBoZXJlCiAgIyAocmV0YWlucyBpbnRlcmNlcHQgYXQgaW5kZXggemVybykKICBjb2VmX2kgPSAoY29lZihmaXRfZ2xtbmV0X2N2LCBzID0gImxhbWJkYS4xc2UiKSlAaQogIGxhYnMgPSBsYWJlbHMoY29lZihmaXRfZ2xtbmV0X2N2LCBzID0gImxhbWJkYS4xc2UiKSlbWzFdXQogIGxhYnMgPSBsYWJzWy0xXSAjIHJlbW92ZSBpbnRlcmNlcHQKICBnbG1uZXRfcmV0YWluZWQgPSBsYWJzW2NvZWZfaV0KICAKICBzdGFydF9mb3JtID0gYXMuZm9ybXVsYShwYXN0ZSgifiAiLCBwYXN0ZShnbG1uZXRfcmV0YWluZWQgLCBjb2xsYXBzZT0gIisiKSkpCiAgbSA9IGttKHN0YXJ0X2Zvcm0sIGRlc2lnbj1YLCByZXNwb25zZT15LCBudWdnZXQ9bnVnZ2V0LCBwYXJpbml0PXBhcmluaXQsCiAgICAgICAgIG51Z2dldC5lc3RpbT1udWdnZXRFc3RpbSwgbm9pc2UudmFyPW5vaXNlVmFyLCBjb250cm9sPWNvbnRyb2xfbGlzdCkKICAKICByZXR1cm4obGlzdCh4PVgsIHk9eSwgbnVnZ2V0PW51Z2dldCwgbnVnZ2V0RXN0aW09bnVnZ2V0RXN0aW0sCiAgICAgICAgICAgICAgbm9pc2VWYXI9bm9pc2VWYXIsIGVtdWxhdG9yPW0sIHNlZWQ9c2VlZCwgY29lZnM9bUBjb3ZhcmlhbmNlQHJhbmdlLnZhbCwKICAgICAgICAgICAgICB0cmVuZHM9bUB0cmVuZC5jb2VmLCBtZWFuVGVybXM9YWxsLnZhcnMoc3RhcnRfZm9ybSksIGZpdF9nbG1uZXRfY3Y9Zml0X2dsbW5ldF9jdikpCn0KYGBgCgoKYGBge3J9Cgp0d29TdGVwX3NlbnMgPC0gZnVuY3Rpb24oWCwgeSwgbj0yMSwgcHJlZHR5cGUgPSAnVUsnLCBudWdnZXQ9TlVMTCwgbnVnZ2V0RXN0aW09RkFMU0UsIG5vaXNlVmFyPU5VTEwsIHNlZWQ9TlVMTCwgdHJhY2U9RkFMU0UsIG1heGl0PTEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgUkVQT1JUPTEwLCBmYWN0cj0xZTcsIHBndG9sPTAuMCwgcGFyaW5pdD1OVUxMLCBwb3BzaXplPTEwMCl7CiAgIyBTZW5zaXRpdml0eSBhbmFseXNpcyB3aXRoIHR3b1N0ZXAgZW11bGF0b3IuIAogICMgQ2FsY3VsYXRlcyB0aGUgdmFyaWFuY2Ugb2YgdGhlIG91dHB1dCB2YXJpZWQgb25lIGF0IGEgdGltZSBhY3Jvc3MgZWFjaCBpbnB1dC4KICBkID0gbmNvbChYKQogIFhfbm9ybSA8LSBub3JtYWxpemUoWCkKICBYX29hYXQgPC0gb2FhdF9kZXNpZ24oWF9ub3JtLCBuLCBtZWQgPSBUUlVFKQogIGNvbG5hbWVzKFhfb2FhdCkgPSBjb2xuYW1lcyhYKQogIAogIHR3b1N0ZXBfZW0gPSB0d29TdGVwX2dsbW5ldChYPVgsIHk9eSwgbnVnZ2V0PW51Z2dldCwgbnVnZ2V0RXN0aW09bnVnZ2V0RXN0aW0sIG5vaXNlVmFyPW5vaXNlVmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWQsIHRyYWNlPXRyYWNlLCBtYXhpdD1tYXhpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVQT1JUPVJFUE9SVCwgZmFjdHI9ZmFjdHIsIHBndG9sPXBndG9sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJpbml0PXBhcmluaXQsIHBvcHNpemU9cG9wc2l6ZSkKICAKICBvYWF0X3ByZWQgPSBwcmVkaWN0KHR3b1N0ZXBfZW0kZW11bGF0b3IsIG5ld2RhdGEgPSBYX29hYXQsIHR5cGUgPSBwcmVkdHlwZSkKICAKICBzZW5zID0gc2Vuc3ZhcihvYWF0X3ByZWQgPSBvYWF0X3ByZWQsIG49biwgZD1kKQogIG91dCA9IHNlbnMKICBvdXQKfQpgYGAKCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQoKaWYgKGZpbGUuZXhpc3RzKCJvYXRfdHdvc3RlcC5yZGF0YSIpKSB7CiAgbG9hZCgib2F0X3R3b3N0ZXAucmRhdGEiKQp9IGVsc2UgewpvYXRfdGVzdCA8LSB0d29TdGVwX3NlbnMoWCA9IFhfbGV2ZWwxLCB5ID0geV9sZXZlbDEpCgoKc2F2ZShvYXRfdGVzdCwgZmlsZSA9ICJvYXRfdHdvc3RlcC5yZGF0YSIpCn0KCmBgYAoKCmBgYHtyfQp5X25hbWVzX3N1bSA8LSBjKCduYnBfbG5kX3N1bScsICdmTHVjX2xuZF9zdW0nLCAnbnBwX25saW1fbG5kX3N1bScsICdjU29pbF9sbmRfc3VtJywKICAgICAgICAgICAgJ2NWZWdfbG5kX3N1bScsICdsYW5kQ292ZXJGcmFjX2xuZF9zdW0nLCAnZkhhcnZlc3RfbG5kX3N1bScsCiAgICAgICAgICAgICdsYWlfbG5kX3N1bScsICdyaF9sbmRfc3VtJywgJ3RyZWVGcmFjX2xuZF9zdW0nLCAnYzNQZnRGcmFjX2xuZF9zdW0nLCAKICAgICAgICAgICAgJ2M0UGZ0RnJhY19sbmRfc3VtJywgJ3NocnViRnJhY19sbmRfc3VtJywgJ2JhcmVzb2lsRnJhY19sbmRfc3VtJykKCgoKCmlmIChmaWxlLmV4aXN0cygib2FhdF9ZLnJkYXRhIikpIHsKICBsb2FkKCJvYWF0X1kucmRhdGEiKQp9IGVsc2UgewogIAogIApvYXRfdmFyX3NlbnNtYXRfWSA8LSBtYXRyaXgoTkEsIG5yb3cgPSBsZW5ndGgoeV9uYW1lc19zdW0pLCBuY29sID0gbmNvbChYX2xldmVsMSkpCgpmb3IoaSBpbiAxOmxlbmd0aCh5X25hbWVzX3N1bSkpewogIAogIHluYW1lIDwtIHlfbmFtZXNfc3VtW2ldCiAgeSA8LSBZX2xldmVsMVssIHluYW1lXQogIG9hdCA8LSB0d29TdGVwX3NlbnMoWCA9IFhfbGV2ZWwxLCB5ID0geSkKICBvYXRfdmFyX3NlbnNtYXRfWVtpLCBdIDwtIG9hdAp9CgpzYXZlKHlfbmFtZXNfc3VtLCBvYXRfdmFyX3NlbnNtYXRfWSwgZmlsZSA9ICJvYWF0X1kucmRhdGEiKQp9CmBgYAoKIyMgSW5pdGlhbCBzZW5zaXRpdml0eSBNYXRyaXgKSXQgbG9va3MgYXMgdGhvdWdoIGJ3bF9pbyBpcyB2ZXJ5IGluZmx1ZW50aWFsIGFjcm9zcyBhIG51bWJlciBvZiB2YXJpYWJsZXMsIGV2ZW4gdGhvdWdoIGl0IGRpZG4ndCBhcHBlYXIgdGhhdCBpbnRlcmVzdGluZyBpbiB0aGUgcGFyZ2luYWwgcGxvdHMuIFdoeSBpcyB0aGF0PwoKYGBge3IsIGZpZy53aWR0aD0gMTAsIGZpZy5oZWlnaHQgPSA2fQojIG5vcm1hbGl6ZSB0aGUgc2Vuc2l0aXZpdHkgbWF0cml4CmNvbG5hbWVzKG9hdF92YXJfc2Vuc21hdF9ZKSA8LSBjb2xuYW1lcyhYX2xldmVsMSkKcm93bmFtZXMob2F0X3Zhcl9zZW5zbWF0X1kpIDwtIHlfbmFtZXNfc3VtCgojdGVzdCA8LSBub3JtYWxpemUodChvYXQudmFyLnNlbnNtYXQpKQoKI2ltYWdlKHRlc3QpCiNwYXIoKQpoZWF0bWFwKG9hdF92YXJfc2Vuc21hdF9ZLCBSb3d2ID0gTkEsIENvbHYgPSBOQSwgbWFyID0gYygxMCwxMCksIHNjYWxlID0gJ3JvdycpCmhlYXRtYXAob2F0X3Zhcl9zZW5zbWF0X1ksIG1hciA9IGMoMTAsMTApLCBzY2FsZSA9ICdyb3cnKQoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9MTIsIGZpZy5oZWlnaHQgPSA3fQoKbm9ybXNlbnNfWSA8LSBub3JtYWxpemUodChvYXRfdmFyX3NlbnNtYXRfWSkpCgpwYXIobWFyID0gYygxMiwxMiw1LDIpKQppbWFnZShub3Jtc2Vuc19ZLCBheGVzID0gRkFMU0UsIGNvbCA9IGJsdWVzKQpheGlzKDEsIGF0ID0gc2VxKGZyb20gPSAwLCB0byA9IDEsIGxlbmd0aC5vdXQgPSBwKSwgbGFiZWxzID0gY29sbmFtZXMoWF9sZXZlbDEpLCBsYXMgPSAyKQpheGlzKDIsIGF0ID0gc2VxKGZyb20gPSAwLCB0byA9IDEsIGxlbmd0aC5vdXQgPSBsZW5ndGgoeV9uYW1lc19zdW0pKSwgbGFiZWxzID0geV9uYW1lc19zdW0sIGxhcyA9IDEpCm10ZXh0KCdPbmUtYXQtYS10aW1lIHNlbnNpdGl2aXR5LCB2YXJpYW5jZSBhY3Jvc3MgbGV2ZWwgMSBlbnNlbWJsZScsIHNpZGUgPSAzLCBhZGogPSAwLCBsaW5lID0gMiwgY2V4ID0gMS44KQoKYGBgCgoKCiMjIFJlLWV4YW1pbmUgYndsX2lvCkEgY2xvc2VyIGxvb2sgYXQgYndsX2lvIG5vdyB0aGF0IHRoZSBpbXBhY3Qgb2YgZjBfaW8gaGFzIGJlZW4gcmVtb3ZlZCBzaG93cyBhIGxhcmdlIG51bWJlciBvZiAiemVybyIgTlBQIHdoZW4gYndsX2lvIGlzIGF0IGxvdyB2YWx1ZXMsIHdoaWNoIGNvdWxkIHdlbGwgYmUgdGhlIHNvdXJjZSBvZiBhcHBhcmVudCBzZW5zaXRpdml0eS4KClRha2Ugb25seSBoaWdoZXIgdmFsdWVzIG9mIGJ3bF9pbyBmb3IgdGhlIG5leHQgcm91bmQgb2YgY29uc3RyYWludHMuCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSAxMn0KCnAgPC0gbmNvbChYX2xldmVsMSkKCnlfbGV2ZWwxIDwtIFlfbGV2ZWwxWywnbnBwX25saW1fbG5kX3N1bSddCgpwYXIobWZyb3cgPSBjKDUsNyksIG1hciA9IGMoMywxLDMsMSkpCmZvcihpIGluIDE6cCl7CiAgcGxvdChYX2xldmVsMVssaV0sIHlfbGV2ZWwxLCB4bGFiID0gJycsIHlsYWIgPSAnJywgbWFpbiA9IGNvbG5hbWVzKFhfbGV2ZWwxKVtpXSkKfQoKYGBgCgojIFJlbW92ZSBlbnNlbWJsZSBtZW1iZXJzIHdpdGggbG93IGJfd2wgYW5kIHNlZSBpZiB0aGUgc2Vuc2l0aXZpdHkgYW5hbHlzZXMgY2hhbmdlIGFuZCB0aGUgZW11bGF0b3JzIGdldCBiZXR0ZXIuCkRlZmluZSBjb25zdHJhaW50IGxldmVsIDFhIGFzIHRob3NlIG1lbWJlcnMgdGhhdCBydW4sIGFuZCBoYXZlIEYwX2lvIDwwLjkgJiBiX3dsX2lvID4gMC4xNSAobm9ybWFsaXNlZCkuCgpgYGB7cn0KbGV2ZWwxYV9peCA8LSB3aGljaChYX2xldmVsMFssICdmMF9pbyddIDwgMC45ICYgWF9sZXZlbDBbLCAnYl93bF9pbyddID4gMC4xNSApCgpYX2xldmVsMWEgPC0gWF9sZXZlbDBbbGV2ZWwxYV9peCwgXQpZX2xldmVsMWEgPC0gWV9sZXZlbDBbbGV2ZWwxYV9peCxdCgpZQW5vbV9sZXZlbDFhIDwtIFlBbm9tX2xldmVsMFtsZXZlbDFhX2l4LCBdCgp5X2xldmVsMWEgPC0gWV9sZXZlbDFhWywgJ25wcF9ubGltX2xuZF9zdW0nXQoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA3LCByZXN1bHRzID0gJ2hpZGUnLCB3YXJuaW5nPUZBTFNFfQplbV9sZXZlbDFhIDwtIGttKH4uLCBkZXNpZ24gPSBYX2xldmVsMWEsICByZXNwb25zZSA9IHlfbGV2ZWwxYSkKYGBgCgoKICMgUGxvdCB0aGUgcmVndWxhciBrbSBlbXVsYXRvci4KCmBgYHtyLCBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gN30KcGxvdChlbV9sZXZlbDFhKQoKCmBgYAoKCmBgYHtyfQppZiAoZmlsZS5leGlzdHMoIm9hYXRfbGV2ZWwxYV9ZLnJkYXRhIikpIHsKICBsb2FkKCJvYWF0X2xldmVsMWFfWS5yZGF0YSIpCn0gZWxzZSB7CiAgCiAgCm9hdF92YXJfc2Vuc21hdF9sZXZlbDFhX1kgPC0gbWF0cml4KE5BLCBucm93ID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSwgbmNvbCA9IG5jb2woWF9sZXZlbDFhKSkKCmZvcihpIGluIDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSl7CiAgCiAgeW5hbWUgPC0geV9uYW1lc19zdW1baV0KICB5IDwtIFlfbGV2ZWwxYVssIHluYW1lXQogIG9hdCA8LSB0d29TdGVwX3NlbnMoWCA9IFhfbGV2ZWwxYSwgeSA9IHkpCiAgb2F0X3Zhcl9zZW5zbWF0X2xldmVsMWFfWVtpLCBdIDwtIG9hdAp9CgpzYXZlKHlfbmFtZXNfc3VtLCBvYXRfdmFyX3NlbnNtYXRfbGV2ZWwxYV9ZLCBmaWxlID0gIm9hYXRfbGV2ZWwxYV9ZLnJkYXRhIikKfQoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gMTJ9CgpwIDwtIG5jb2woWF9sZXZlbDFhKQoKeV9sZXZlbDFhIDwtIFlfbGV2ZWwxYVssJ25wcF9ubGltX2xuZF9zdW0nXQoKcGFyKG1mcm93ID0gYyg1LDcpLCBtYXIgPSBjKDMsMSwzLDEpKQpmb3IoaSBpbiAxOnApewogIHBsb3QoWF9sZXZlbDFhWyxpXSwgeV9sZXZlbDFhLCB4bGFiID0gJycsIHlsYWIgPSAnJywgbWFpbiA9IGNvbG5hbWVzKFhfbGV2ZWwxYSlbaV0sIHhsaW0gPSBjKDAsMSkpCn0KCmBgYAoKIyMgV2l0aCBiX3dsIHRydW5jYXRlZCwgd2UgY2FuIGNsZWFybHkgc2VlIHRoZSBzZW5zaXRpdml0aWVzIGNoYW5nZS4KCmBgYHtyLCBmaWcud2lkdGg9IDEwLCBmaWcuaGVpZ2h0ID0gNn0KIyBub3JtYWxpemUgdGhlIHNlbnNpdGl2aXR5IG1hdHJpeApjb2xuYW1lcyhvYXRfdmFyX3NlbnNtYXRfbGV2ZWwxYV9ZKSA8LSBjb2xuYW1lcyhYX2xldmVsMWEpCnJvd25hbWVzKG9hdF92YXJfc2Vuc21hdF9sZXZlbDFhX1kpIDwtIHlfbmFtZXNfc3VtCgojdGVzdCA8LSBub3JtYWxpemUodChvYXQudmFyLnNlbnNtYXQpKQoKI2ltYWdlKHRlc3QpCiNwYXIoKQpoZWF0bWFwKG9hdF92YXJfc2Vuc21hdF9sZXZlbDFhX1ksIFJvd3YgPSBOQSwgQ29sdiA9IE5BLCBtYXIgPSBjKDEwLDEwKSwgc2NhbGUgPSAncm93JykKaGVhdG1hcChvYXRfdmFyX3NlbnNtYXRfbGV2ZWwxYV9ZLCBtYXIgPSBjKDEwLDEwKSwgc2NhbGUgPSAncm93JykKCmBgYAoKCmBgYHtyLCBmaWcud2lkdGggPTEyLCBmaWcuaGVpZ2h0ID0gN30KCm5vcm1zZW5zX2xldmVsMWFfWSA8LSBub3JtYWxpemUodChvYXRfdmFyX3NlbnNtYXRfbGV2ZWwxYV9ZKSkKCnBhcihtYXIgPSBjKDEyLDEyLDUsMikpCmltYWdlKG5vcm1zZW5zX2xldmVsMWFfWSwgYXhlcyA9IEZBTFNFLCBjb2wgPSBibHVlcykKYXhpcygxLCBhdCA9IHNlcShmcm9tID0gMCwgdG8gPSAxLCBsZW5ndGgub3V0ID0gcCksIGxhYmVscyA9IGNvbG5hbWVzKFhfbGV2ZWwxYSksIGxhcyA9IDIpCmF4aXMoMiwgYXQgPSBzZXEoZnJvbSA9IDAsIHRvID0gMSwgbGVuZ3RoLm91dCA9IGxlbmd0aCh5X25hbWVzX3N1bSkpLCBsYWJlbHMgPSB5X25hbWVzX3N1bSwgbGFzID0gMSkKbXRleHQoJ09uZS1hdC1hLXRpbWUgc2Vuc2l0aXZpdHksIHZhcmlhbmNlIGFjcm9zcyBsZXZlbCAxYSBlbnNlbWJsZScsIHNpZGUgPSAzLCBhZGogPSAwLCBsaW5lID0gMiwgY2V4ID0gMS44KQoKYGBgCgoKCmBgYHtyfQojIFRoaXMgZmFpbHMgZm9yICJjVmVnX2xuZF9zdW0iCiMgVGhlIHJlc3VsdCB3aWxsIGJlIHRoYXQgc29tZSBvZiB0aGUgY29sdW1ucyBhcmUgcmVwZWF0ZWQuCgppZiAoZmlsZS5leGlzdHMoIm9hYXRfWUFub20ucmRhdGEiKSkgewogIGxvYWQoIm9hYXRfWUFub20ucmRhdGEiKQp9IGVsc2UgewoKb2F0X3Zhcl9zZW5zbWF0X1lBbm9tIDwtIG1hdHJpeChOQSwgbnJvdyA9IGxlbmd0aCh5X25hbWVzX3N1bSksIG5jb2wgPSBuY29sKFhfbGV2ZWwxKSkKCmZvcihpIGluIDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSl7CiAgCiAgeW5hbWUgPC0geV9uYW1lc19zdW1baV0KICB5IDwtIFlBbm9tX2xldmVsMVssIHluYW1lXQogIHRyeShvYXQgPC0gdHdvU3RlcF9zZW5zKFggPSBYX2xldmVsMSwgeSA9IHkpKQogIG9hdF92YXJfc2Vuc21hdF9ZQW5vbVtpLCBdIDwtIG9hdAp9CgpzYXZlKHlfbmFtZXNfc3VtLCBvYXRfdmFyX3NlbnNtYXRfWUFub20sIGZpbGUgPSAib2FhdF9ZQW5vbS5yZGF0YSIpCgp9CmBgYAoKCgpgYGB7ciwgZmlnLndpZHRoPSAxMCwgZmlnLmhlaWdodCA9IDZ9CiMgbm9ybWFsaXplIHRoZSBzZW5zaXRpdml0eSBtYXRyaXgKY29sbmFtZXMob2F0X3Zhcl9zZW5zbWF0X1lBbm9tKSA8LSBjb2xuYW1lcyhYX2xldmVsMSkKcm93bmFtZXMob2F0X3Zhcl9zZW5zbWF0X1lBbm9tKSA8LSB5X25hbWVzX3N1bQoKI3Rlc3QgPC0gbm9ybWFsaXplKHQob2F0LnZhci5zZW5zbWF0KSkKCiNpbWFnZSh0ZXN0KQojcGFyKCkKaGVhdG1hcChvYXRfdmFyX3NlbnNtYXRfWUFub20sIFJvd3YgPSBOQSwgQ29sdiA9IE5BLCBtYXIgPSBjKDEwLDEwKSwgc2NhbGUgPSAncm93JykKaGVhdG1hcChvYXRfdmFyX3NlbnNtYXRfWUFub20sIG1hciA9IGMoMTAsNiksIHNjYWxlID0gJ3JvdycpCgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0xMiwgZmlnLmhlaWdodCA9IDd9Cgpub3Jtc2Vuc19ZQW5vbSA8LSBub3JtYWxpemUodChvYXRfdmFyX3NlbnNtYXRfWUFub20pKQoKcGFyKG1hciA9IGMoMTIsMTIsNSwyKSkKaW1hZ2Uobm9ybXNlbnNfWUFub20sIGF4ZXMgPSBGQUxTRSwgY29sID0gYmx1ZXMpCmF4aXMoMSwgYXQgPSBzZXEoZnJvbSA9IDAsIHRvID0gMSwgbGVuZ3RoLm91dCA9IHApLCBsYWJlbHMgPSBjb2xuYW1lcyhYX2xldmVsMSksIGxhcyA9IDIpCmF4aXMoMiwgYXQgPSBzZXEoZnJvbSA9IDAsIHRvID0gMSwgbGVuZ3RoLm91dCA9IGxlbmd0aCh5X25hbWVzX3N1bSkpLCBsYWJlbHMgPSB5X25hbWVzX3N1bSwgbGFzID0gMSkKbXRleHQoJ09uZS1hdC1hLXRpbWUgc2Vuc2l0aXZpdHksIHZhcmlhbmNlIG9mIGhpc3RvcmljYWwgY2hhbmdlIGFjcm9zcyBsZXZlbCAxIGVuc2VtYmxlJywgc2lkZSA9IDMsIGFkaiA9IDAsIGxpbmUgPSAyLCBjZXggPSAxLjgpCgpgYGAKCgojIyBQbG90IGJvdGggc2Vuc2l0aXZpdHkgbWF0cmljZXMgb24gdG9wIG9mIG9uZSBhbm90aGVyLgpJdCBsb29rcyBhcyB0aG91Z2ggYm90aCB0aGUgYWJzb2x1dGUgdmFsdWUgYW5kIHRoZSBjaGFuZ2Ugb3ZlciB0aW1lIGFyZSBjb250cm9sbGVkIGJ5IHRoZSBzYW1lIHBhcmFtZXRlcnMuCmBgYHtyLCBmaWcud2lkdGggPTEyLCBmaWcuaGVpZ2h0ID0gMTJ9CnBhcihtZnJvdyA9IGMoMiwxKSwgbWFyID0gYygxMiwxMiw1LDIpKQoKaW1hZ2Uobm9ybXNlbnNfWSwgYXhlcyA9IEZBTFNFLCBjb2wgPSBibHVlcykKYXhpcygxLCBhdCA9IHNlcShmcm9tID0gMCwgdG8gPSAxLCBsZW5ndGgub3V0ID0gcCksIGxhYmVscyA9IGNvbG5hbWVzKFhfbGV2ZWwxKSwgbGFzID0gMikKYXhpcygyLCBhdCA9IHNlcShmcm9tID0gMCwgdG8gPSAxLCBsZW5ndGgub3V0ID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSksIGxhYmVscyA9IHlfbmFtZXNfc3VtLCBsYXMgPSAxKQptdGV4dCgnT25lLWF0LWEtdGltZSBzZW5zaXRpdml0eSwgdmFyaWFuY2Ugb2YgaGlzdG9yaWNhbCBjaGFuZ2UgYWNyb3NzIGxldmVsIDEgZW5zZW1ibGUnLCBzaWRlID0gMywgYWRqID0gMCwgbGluZSA9IDIsIGNleCA9IDEuOCkKCgppbWFnZShub3Jtc2Vuc19ZQW5vbSwgYXhlcyA9IEZBTFNFLCBjb2wgPSBibHVlcykKYXhpcygxLCBhdCA9IHNlcShmcm9tID0gMCwgdG8gPSAxLCBsZW5ndGgub3V0ID0gcCksIGxhYmVscyA9IGNvbG5hbWVzKFhfbGV2ZWwxKSwgbGFzID0gMikKYXhpcygyLCBhdCA9IHNlcShmcm9tID0gMCwgdG8gPSAxLCBsZW5ndGgub3V0ID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSksIGxhYmVscyA9IHlfbmFtZXNfc3VtLCBsYXMgPSAxKQptdGV4dCgnT25lLWF0LWEtdGltZSBzZW5zaXRpdml0eSwgdmFyaWFuY2Ugb2YgaGlzdG9yaWNhbCBjaGFuZ2UgYWNyb3NzIGxldmVsIDEgZW5zZW1ibGUnLCBzaWRlID0gMywgYWRqID0gMCwgbGluZSA9IDIsIGNleCA9IDEuOCkKCgpgYGAKCgojIyBIb3cgZ29vZCBhcmUgdGhlIGVtdWxhdG9ycyBmb3IgZWFjaCBvdXRwdXQ/ClRoZSBlbXVsYXRvcnMgYXBwZWFyIHRvIGJlIGF0IGxlYXN0IGNhcHR1cmluZyB0aGUgYnJvYWQgcmVzcG9uc2UgZm9yIGFsbCBvZiB0aGUgb3V0cHV0IHZhcmlhYmxlcy4KCkZpcnN0LCBwbG90IHRoZSBzdHJhaWdodCBrcmlnaW5nIGVtdWxhdG9ycwoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNiwgcmVzdWx0cyA9ICdoaWRlJ30KCmlmIChmaWxlLmV4aXN0cygia21fZW11bGF0b3JzX1kucmRhdGEiKSkgewogIGxvYWQoImttX2VtdWxhdG9yc19ZLnJkYXRhIikKfSBlbHNlIHsKICAKICBlbWxpc3Rfa21fWSA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSkKICAKICBmb3IoaSBpbiAxOmxlbmd0aCh5X25hbWVzX3N1bSkpewogICAgeW5hbWUgPC0geV9uYW1lc19zdW1baV0KICAgIHkgPC0gWV9sZXZlbDFbLCB5bmFtZV0KICAgIAogICAgZW0gPC0ga20ofi4sIGRlc2lnbiA9IFhfbGV2ZWwxLCByZXNwb25zZSA9IHkpCiAgICBlbWxpc3Rfa21fWVtbaV1dIDwtIGVtCiAgfQogIAogIGxvb2xpc3Rfa21fWSA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSkKICAKICBmb3IoaSBpbiAxOmxlbmd0aCh5X25hbWVzX3N1bSkpewogICAgCiAgICBsb28gPC0gbGVhdmVPbmVPdXQua20obW9kZWwgPSBlbWxpc3Rfa21fWVtbaV1dLCB0eXBlID0gJ1VLJywgdHJlbmQucmVlc3RpbSA9IFRSVUUpCiAgICBsb29saXN0X2ttX1lbW2ldXSA8LSBsb28KICB9CiAgCiAgc2F2ZShlbWxpc3Rfa21fWSxsb29saXN0X2ttX1ksIGZpbGUgPSAia21fZW11bGF0b3JzX1kucmRhdGEiKQp9CgpgYGAKCmBgYHtyfQoKCmxvb3N0YXRzX2ttX1kgPC0gdmVjdG9yKG1vZGUgPSAnbGlzdCcsIGxlbmd0aCA9IGxlbmd0aCh5X25hbWVzX3N1bSkpCgpmb3IoaSBpbiAxOmxlbmd0aChlbWxpc3Rfa21fWSkpewogIAogIGxvb3N0YXRzIDwtIGttTG9vU3RhdHMoZW1saXN0X2ttX1lbW2ldXSkKICBsb29zdGF0c19rbV9ZW1tpXV0gPC0gbG9vc3RhdHMKICBwcmludChsb29zdGF0cyRwbWFlKQp9CgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSAxMn0KcGFyKG1mcm93ID0gYyg0LDQpLCBtYXIgPSBjKDMsNCwyLDIpLCBvbWEgPSBjKDQsNCw0LDAuMSkpCmZvcihpIGluIDE6bGVuZ3RoKGxvb2xpc3Rfa21fWSkpewogIAogIHkgPC0gWV9sZXZlbDFbLCB5X25hbWVzX3N1bVtpXV0KICBsb28gPC0gbG9vbGlzdF9rbV9ZW1tpXV0KICB5bGltIDwtIHJhbmdlKGMobG9vJG1lYW4gLSAoMipsb28kc2QpLCBsb28kbWVhbiArICgyKmxvbyRzZCkpICkKICBwbG90KHksIGxvbyRtZWFuLCB4bGFiID0gJycsIHlsYWIgPSAnJywgbWFpbiA9IHlfbmFtZXNfc3VtW2ldICwgeWxpbSA9IHlsaW0sIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgnYmxhY2snLCA3MCksCiAgICAgICBwY2ggPSAxOSkKICBzZWdtZW50cyh4MCA9IHksIHkwID0gbG9vJG1lYW4gLSAoMipsb28kc2QpICAsIHgxID0geSAsIHkxID0gbG9vJG1lYW4gKyAoMipsb28kc2QpLCBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ2JsYWNrJywgNzApKQogIGFibGluZSgwLDEpCiAgbGVnZW5kKCdib3R0b21yaWdodCcsbGVnZW5kID0gcGFzdGUoJ21hZSA9Jyxyb3VuZChsb29zdGF0c19rbV9ZW1tpXV0kcG1hZSwyKSwnJScpICwgYnR5ID0gJ24nKQoKfQoKbXRleHQoJ0FjdHVhbCcsIHNpZGUgPSAxLCBsaW5lID0gMSwgb3V0ZXIgPSBUUlVFLCBjZXggPSAyICkKbXRleHQoJ1ByZWRpY3RlZCcsIHNpZGUgPSAyLCBsaW5lID0gMCwgb3V0ZXIgPSBUUlVFLCBjZXggPSAyKSAKbXRleHQoJ01vZGVybiBWYWx1ZSAoWSknLCBzaWRlID0gMywgbGluZSA9IDAsIG91dGVyID0gVFJVRSwgY2V4ID0gMikgCgpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDYsIHJlc3VsdHMgPSAnaGlkZSd9CgppZiAoZmlsZS5leGlzdHMoImttX2VtdWxhdG9yc19ZQW5vbS5yZGF0YSIpKSB7CiAgbG9hZCgia21fZW11bGF0b3JzX1lBbm9tLnJkYXRhIikKfSBlbHNlIHsKICAKICBlbWxpc3Rfa21fWUFub20gPC0gdmVjdG9yKG1vZGUgPSAnbGlzdCcsIGxlbmd0aCA9IGxlbmd0aCh5X25hbWVzX3N1bSkpCiAgCiAgZm9yKGkgaW4gMTpsZW5ndGgoeV9uYW1lc19zdW0pKXsKICAgIHluYW1lIDwtIHlfbmFtZXNfc3VtW2ldCiAgICB5IDwtIFlBbm9tX2xldmVsMVssIHluYW1lXQogICAgCiAgICBlbSA8LSBrbSh+LiwgZGVzaWduID0gWF9sZXZlbDEsIHJlc3BvbnNlID0geSkKICAgIGVtbGlzdF9rbV9ZQW5vbVtbaV1dIDwtIGVtCiAgfQogIAogIGxvb2xpc3Rfa21fWUFub20gPC0gdmVjdG9yKG1vZGUgPSAnbGlzdCcsIGxlbmd0aCA9IGxlbmd0aCh5X25hbWVzX3N1bSkpCiAgCiAgZm9yKGkgaW4gMTpsZW5ndGgoeV9uYW1lc19zdW0pKXsKICAgIAogICAgbG9vIDwtIGxlYXZlT25lT3V0LmttKG1vZGVsID0gZW1saXN0X2ttX1lBbm9tW1tpXV0sIHR5cGUgPSAnVUsnLCB0cmVuZC5yZWVzdGltID0gVFJVRSkKICAgIGxvb2xpc3Rfa21fWUFub21bW2ldXSA8LSBsb28KICB9CiAgCiAgc2F2ZShlbWxpc3Rfa21fWUFub20sbG9vbGlzdF9rbV9ZQW5vbSwgZmlsZSA9ICJrbV9lbXVsYXRvcnNfWUFub20ucmRhdGEiKQp9CgpgYGAKCgojIGttIGVtdWxhdG9ycyBmb3IgY2hhbmdlIGluIHZhcmlhYmxlcyBvdmVyIHRpbWUKCmBgYHtyLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDEyfQpwYXIobWZyb3cgPSBjKDQsNCksIG1hciA9IGMoMyw0LDIsMiksIG9tYSA9IGMoNCw0LDQsMC4xKSkKZm9yKGkgaW4gMTpsZW5ndGgobG9vbGlzdF9rbV9ZQW5vbSkpewogIAogIHkgPC0gWUFub21fbGV2ZWwxWywgeV9uYW1lc19zdW1baV1dCiAgbG9vIDwtIGxvb2xpc3Rfa21fWUFub21bW2ldXQogIHlsaW0gPC0gcmFuZ2UoYyhsb28kbWVhbiAtICgyKmxvbyRzZCksIGxvbyRtZWFuICsgKDIqbG9vJHNkKSkgKQogIHBsb3QoeSwgbG9vJG1lYW4sIHhsYWIgPSAnJywgeWxhYiA9ICcnLCBtYWluID0geV9uYW1lc19zdW1baV0gLCB5bGltID0geWxpbSwgY29sID0gbWFrZVRyYW5zcGFyZW50KCdibGFjaycsIDcwKSwKICAgICAgIHBjaCA9IDE5KQogIHNlZ21lbnRzKHgwID0geSwgeTAgPSBsb28kbWVhbiAtICgyKmxvbyRzZCkgICwgeDEgPSB5ICwgeTEgPSBsb28kbWVhbiArICgyKmxvbyRzZCksIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgnYmxhY2snLCA3MCkpCiAgYWJsaW5lKDAsMSkKICAKCn0KCm10ZXh0KCdBY3R1YWwnLCBzaWRlID0gMSwgbGluZSA9IDEsIG91dGVyID0gVFJVRSwgY2V4ID0gMiApCm10ZXh0KCdQcmVkaWN0ZWQnLCBzaWRlID0gMiwgbGluZSA9IDAsIG91dGVyID0gVFJVRSwgY2V4ID0gMikgCm10ZXh0KCdDaGFuZ2Ugb3ZlciB0aW1lIChZQW5vbSknLCBzaWRlID0gMywgbGluZSA9IDEsIG91dGVyID0gVFJVRSwgY2V4ID0gMikgCgpgYGAKCk5leHQsIHBsb3QgdGhlIHR3b3N0ZXAgZ2xtbmV0L2ttIGVtdWxhdG9ycwoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNn0KIyBUd29zdGVwIGdsbW5ldCBlbXVsYXRvcnMKCmlmIChmaWxlLmV4aXN0cygidHNfZW11bGF0b3JzX1kucmRhdGEiKSkgewogIGxvYWQoInRzX2VtdWxhdG9yc19ZLnJkYXRhIikKfSBlbHNlIHsKICAKICBlbWxpc3RfdHdvU3RlcF9nbG1uZXRfWSA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSkKICAKICBmb3IoaSBpbiAxOmxlbmd0aCh5X25hbWVzX3N1bSkpewogICAgCiAgICB5bmFtZSA8LSB5X25hbWVzX3N1bVtpXQogICAgeSA8LSBZX2xldmVsMVssIHluYW1lXQogICAgCiAgICBlbSA8LSB0d29TdGVwX2dsbW5ldChYID0gWF9sZXZlbDEsIHkgPSB5KQogICAgZW1saXN0X3R3b1N0ZXBfZ2xtbmV0X1lbW2ldXSA8LSBlbQogIH0KICAKICBsb29saXN0X3R3b1N0ZXBfZ2xtbmV0X1kgPC0gdmVjdG9yKG1vZGUgPSAnbGlzdCcsIGxlbmd0aCA9IGxlbmd0aCh5X25hbWVzX3N1bSkpCiAgCiAgZm9yKGkgaW4gMTpsZW5ndGgoeV9uYW1lc19zdW0pKXsKICAgIAogICAgbG9vIDwtIGxlYXZlT25lT3V0LmttKG1vZGVsID0gZW1saXN0X3R3b1N0ZXBfZ2xtbmV0X1lbW2ldXSRlbXVsYXRvciwgdHlwZSA9ICdVSycsIHRyZW5kLnJlZXN0aW0gPSBUUlVFKQogICAgbG9vbGlzdF90d29TdGVwX2dsbW5ldF9ZW1tpXV0gPC0gbG9vCiAgfQogIAogIAogIAogIHNhdmUoZW1saXN0X3R3b1N0ZXBfZ2xtbmV0X1ksIGxvb2xpc3RfdHdvU3RlcF9nbG1uZXRfWSwgZmlsZSA9ICJ0c19lbXVsYXRvcnNfWS5yZGF0YSIpCgp9CgoKYGBgCgpgYGB7cn0KIyBDYW4gZ2V0IG51bWVyaWNhbCBwZXJmb3JtYW5jZSB1c2luZwoKbG9vc3RhdHNfdHdvU3RlcF9nbG1uZXRfWSA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbGVuZ3RoKHlfbmFtZXNfc3VtKSkKCmZvcihpIGluIDE6bGVuZ3RoKGVtbGlzdF90d29TdGVwX2dsbW5ldF9ZKSl7CiAgCiAgbG9vc3RhdHMgPC0ga21Mb29TdGF0cyhlbWxpc3RfdHdvU3RlcF9nbG1uZXRfWVtbaV1dJGVtdWxhdG9yKQogIGxvb3N0YXRzX3R3b1N0ZXBfZ2xtbmV0X1lbW2ldXSA8LSBsb29zdGF0cwogIHByaW50KGxvb3N0YXRzJHBtYWUpCn0KCgpgYGAKCgoKIyMgVHdvU3RlcCBlbXVsYXRvciBwZXJmb3JtYW5jZSBmb3IgbW9kZXJuIHZhbHVlcwoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gMTJ9CnBhcihtZnJvdyA9IGMoNCw0KSwgbWFyID0gYygzLDQsMiwyKSwgb21hID0gYyg0LDQsNCwwLjEpKQpmb3IoaSBpbiAxOmxlbmd0aChsb29saXN0X3R3b1N0ZXBfZ2xtbmV0X1kpKXsKICAKICB5IDwtIFlfbGV2ZWwxWywgeV9uYW1lc19zdW1baV1dCiAgbG9vIDwtIGxvb2xpc3RfdHdvU3RlcF9nbG1uZXRfWVtbaV1dCiAgeWxpbSA8LSByYW5nZShjKGxvbyRtZWFuIC0gKDIqbG9vJHNkKSwgbG9vJG1lYW4gKyAoMipsb28kc2QpKSApCiAgcGxvdCh5LCBsb28kbWVhbiwgeGxhYiA9ICcnLCB5bGFiID0gJycsIG1haW4gPSB5X25hbWVzX3N1bVtpXSAsIHlsaW0gPSB5bGltLCBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ2JsYWNrJywgNzApLAogICAgICAgcGNoID0gMTkpCiAgc2VnbWVudHMoeDAgPSB5LCB5MCA9IGxvbyRtZWFuIC0gKDIqbG9vJHNkKSAgLCB4MSA9IHkgLCB5MSA9IGxvbyRtZWFuICsgKDIqbG9vJHNkKSwgY29sID0gbWFrZVRyYW5zcGFyZW50KCdibGFjaycsIDcwKSkKICBhYmxpbmUoMCwxKQogIGxlZ2VuZCgnYm90dG9tcmlnaHQnLGxlZ2VuZCA9IHBhc3RlKCdtYWUgPScscm91bmQobG9vc3RhdHNfdHdvU3RlcF9nbG1uZXRfWVtbaV1dJHBtYWUsMiksJyUnKSAsIGJ0eSA9ICduJykKCn0KCm10ZXh0KCdBY3R1YWwnLCBzaWRlID0gMSwgbGluZSA9IDEsIG91dGVyID0gVFJVRSwgY2V4ID0gMiApCm10ZXh0KCdQcmVkaWN0ZWQnLCBzaWRlID0gMiwgbGluZSA9IDAsIG91dGVyID0gVFJVRSwgY2V4ID0gMikgCm10ZXh0KCdNb2Rlcm4gVmFsdWUgKFkpJywgc2lkZSA9IDMsIGxpbmUgPSAwLCBvdXRlciA9IFRSVUUsIGNleCA9IDIpIAoKYGBgCgojIENvbXBhcmUgTGVhdmUtb25lLW91dCBzdGF0aXN0aWNzIGZvciB0aGUgdHdvIHR5cGVzIG9mIGVtdWxhdG9yCgpXZSB1c2UgdGhlIGxlYXZlLW9uZS1vdXQgTWVhbiBBYnNvbHV0ZSBFcnJvciwgZXhwcmVzc2VkIGFzIGEgcGVyY2VudGFnZSBvZiB0aGUgcmFuZ2Ugb2YgdGhlIG91dHB1dCBhY3Jvc3MgdGhlIGVuc2VtYmxlLiBXZSBmaW5kIHRoYXQgdGhlIHR3b3N0ZXAgZW11bGF0b3Jpc24ndCBzaWduaWZpY2FudGx5IG1vcmUgYWNjdXJhdGUsIGFuZCBpcyBpbmRlZWQgKmxlc3MqIGFjY3VyYXRlIGZvciB0cmVlIGZyYWN0aW9uLgoKYGBge3IsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA3fQoKCmttX3BtYWUgPC0gc2FwcGx5KGxvb3N0YXRzX2ttX1ksICdbWycsICdwbWFlJykKdHNfcG1hZSA8LSBzYXBwbHkobG9vc3RhdHNfdHdvU3RlcF9nbG1uZXRfWSwgJ1tbJywgJ3BtYWUnKQoKcGFyKG1hciA9IGMoMTIsNCwyLDEpLCBsYXMgPTEgKQpwbG90KDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSwga21fcG1hZSwKICAgICB5bGltID0gYygwLDE1KSwgcGNoID0gMTksCiAgICAgYXhlcyA9IEZBTFNFLCB4bGFiID0gJycsIAogICAgIHlsYWIgPSAnTE9PIE1BRSAoJSBvZiByYW5nZSknLAogICAgIGNleCA9IDEuMikKcG9pbnRzKDE6bGVuZ3RoKHlfbmFtZXNfc3VtKSx0c19wbWFlICwgY29sPSAncmVkJywgcGNoID0gMTksIGNleCA9IDEuMikKbGVnZW5kKCd0b3BsZWZ0JywgYygna20gZW11bGF0b3InLCAndHdvU3RlcCBlbXVsYXRvcicpLCBwY2ggPSAxOSwgY29sID0gYygnYmxhY2snLCAncmVkJyksIHB0LmNleCA9IDEuMikKYXhpcyAoMikKcGFyKGxhcyA9IDIpCmF4aXMoMSwgYXQgPSAxOmxlbmd0aCh5X25hbWVzX3N1bSksIGxhYmVscyA9IHlfbmFtZXNfc3VtKQoKYGBgCgoKCmBgYHtyfQoKIyBXcml0ZSBhbiBlbXVsYXRvciB3cmFwcGVyCgojIFdyaXRlIGEgbGVhdmUtb25lLW91dCB3cmFwcGVyCgojIENyZWF0ZSBhIGxpc3Qgb2YgZW11bGF0b3IgZml0cywgZm9yIGJvdGgga20gYW5kIHR3b1N0ZXAgbWV0aG9kcy4KIyBVc2UgbWNsYXBwbHkgdG8gYnVpbGQgdGhlIGxpc3RzCiMgdXNlIGNvZGUgZnJvbSBIREUgcGFja2FnZQojIE1ha2Ugc3VyZSBlcnJvcnMgYXJlIGhhbmRsZWQgYWRlcXVhdGVseS4KCgojIENhbiB3ZSB3cml0ZSBpdCB0byB1c2UgYW55IGVtdWxhdG9yPyAoaS5lIGttLCB0d29zdGVwLCBzb21ldGhpbmcgZnJvbSBhbm90aGVyIHBhY2thZ2U/KQpgYGAKCgoKIyBIaXN0b3J5IG1hdGNoaW5nIGFuZCBnZW5lcmF0aW9uIG9mIG5ldyBlbnNlbWJsZSBtZW1iZXJzClRvIHVzZSBIaXN0b3J5IE1hdGNoaW5nLCB3ZSBuZWVkIHRvIHNwZWNpZnkgdGFyZ2V0cyBmb3IgdmFyaW91cyBtb2RlbCBvdXRwdXRzLiBXZSB0cmVhdCB0aGVzZSB0YXJnZXRzIGFzICJvYnNlcnZhdGlvbnMiIHdpdGggYW4gdW5jZXJ0YWludHkgd2hlcmUgYSBtb2RlbCBydW4gbWFya2VkIGFzICJpbXBsYXVzaWJsZSIgKGJleW9uZCAzc2QpIG1hdGNoZXMgdGhlIGhhcmQgYm91bmRhcmllcyBwcmV2aW91c2x5IGlkZW50aWZpZWQgYnkgQS4gV2lsdHNoaXJlIGFzIGJlaW5nIGRlc2lyYWJsZS4KCkNob29zZSB0aGUgY2VudHJlIG9mIHRoZSAoaW1wbGllZCkgdW5pZm9ybSBkaXN0cmlidXRpb24uCiBjc19nYi50YXJnZXQgPSAoMzAwMCAtIDc1MCkgLyAyID0gIDExMjUKIGN2LnRhcmdldCA9ICg4MDAgLSAzMDApIC8gMiA9IDI1MAogbnBwX25fZ2IudGFyZ2V0ID0gKDgwIC0gMzUpIC8gMiA9IDIyLjUKCiBuYnAudGFyZ2V0ID0gMAogKGdwcC50YXJnZXQgPSA3NSkKIChydW5vZmYudGFyZ2V0ID0gMSkKIAoodG8gZG86IHZpc3VhbGlzZSBpbXBsYXVzaWJpbGl0eSBvZiBkZXNpZ24gYW5kIGxvbyBlbXVsYXRlZCB2YWx1ZXMgb2YgZGVzaWduIGFzIGhpc3RvZ3JhbSkgCgpgYGB7cn0KCiNZLnRhcmdldCA9IGMoY3NfZ2IudGFyZ2V0LCBjdi50YXJnZXQsIG5wcF9uX2diLnRhcmdldCwgcnVub2ZmLnRhcmdldCwgbmJwLnRhcmdldCkKCnluYW1lc19jb25zdCA8LSBjKCduYnBfbG5kX3N1bScsICducHBfbmxpbV9sbmRfc3VtJywgJ2NTb2lsX2xuZF9zdW0nLCAnY1ZlZ19sbmRfc3VtJykKeXVuaXRzX2NvbnN0IDwtIGMoJ0d0Qy95ZWFyJywgJ0d0Qy95ZWFyJywgJ0d0QycsICdHdEMnKQpZX2NvbnN0X2xldmVsMWEgPC0gWV9sZXZlbDFhWywgeW5hbWVzX2NvbnN0XQoKc2NhbGV2ZWMgPC0gYygxZTEyL3lzZWMsIDFlMTIveXNlYywgMWUxMiwgMWUxMikKWV9jb25zdF9sZXZlbDFhX3NjYWxlZCA8LSBzd2VlcChZX2NvbnN0X2xldmVsMWEsIDIsIFNUQVRTID0gc2NhbGV2ZWMsIEZVTiA9ICcvJyApCgojIFRoaXMgaXMgYSAibm9ybWFsaXNhdGlvbiB2ZWN0b3IiLCBmb3IgbWFraW5nIHRoZSBvdXRwdXQgbnVtYmVycyBtb3JlIG1hbmFnZWFibGUuCiNjc19nYiAgICAgICBjdiAgICBncHBfZ2IgICAgICAgIG5icCBucHBfbl9nYiAgICBydW5vZmYKbm9ybV92ZWMgPSBjKDFlMTIsIDFlMTIsIDFlMTIveXNlYyAsIDFlMTIsIDFlMTIsIDFlOSkKCiMgbmJwICBucHAgIGNzb2lsICBjdmVnCllfbG93ZXIgPC0gYygtMTAsIDM1LCA3NTAsIDMwMCkKWV91cHBlciA8LSBjKDEwLCA4MCwgMzAwMCwgODAwKQoKIyBJJ20gZ29pbmcgdG8gc2V0IGl0IHNvIHRoYXQgKyA0c2QgYWxpZ25zIGFwcHJveGltYXRlbHkgd2l0aCB0aGUgb3JpZ2luYWwgbGltaXRzCiMgZ2l2ZW4gYnkgQW5keSBXaWx0c2hpcmUuIFRoaXMgZ2l2ZXMgcm9vbSBmb3IgdW5jZXJ0YWludHkgZnJvbSB0aGUgZW11bGF0b3IKWV90YXJnZXQgPSBZX3VwcGVyIC0gKGFicyhZX3VwcGVyIC0gKFlfbG93ZXIpKSAvIDIgKSMgYWJzKCkgdG8gZml4IHRoZSBwcm9ibGVtIHdpdGggbmVnYXRpdmUgbnVtYmVycwoKCiMgc3RhbmRhcmQgZGV2aWF0aW9uIGlzIGRlcml2ZWQgZnJvbSB0aGUgbGltaXRzIGFuZCB0aGUgY2VudHJhbCB0YXJnZXQKIyAodGhpcyBkaXN0YW5jZSBpcyBhc3N1bWVkIHRvIGJlIDQgc3RhbmRhcmQgZGV2aWF0aW9ucy4KWV9zZCA9IChZX3VwcGVyIC0gWV90YXJnZXQpIC8gNApuYW1lcyhZX3NkKSA9IGNvbG5hbWVzKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpCgoKcCA9IG5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkKCm9ic19zZF9saXN0ID0gYXMubGlzdChyZXAoMC4wMSxwKSkKZGlzY19saXN0ID0gIGFzLmxpc3QocmVwKDAscCkpIApkaXNjX3NkX2xpc3QgPSAgYXMubGlzdChZX3NkKQp0aHJlcyA9IDMKCm1pbnNfYXVnID0gYXBwbHkoWF9sZXZlbDFhLCAyLCBGVU4gPSBtaW4pCm1heGVzX2F1ZyA9YXBwbHkoWF9sZXZlbDFhLCAyLCBGVU4gPSBtYXgpCgojIGNvbnZlcnQgWV90YXJnZXQgZm9yIGluZ2VzdGlvbiBpbnRvIGZ1bmN0aW9uCllfdGFyZ2V0ID0gbWF0cml4KFlfdGFyZ2V0LCBucm93ID0gMSkKCmBgYAoKCiMjIHZpc3VhbGlzZSB0aGUgY29uc3RyYWludHMKYGBge3J9CgojIEhpc3RvZ3JhbSBvZiBsZXZlbCAxIGNvbnN0cmFpbnRzCmhjb2wgPSAnZGFya2dyZXknCmxjb2wgPSAnYmxhY2snCnBhcihtZnJvdyA9IGMoMiwyKSwgZmcgPSAnZGFya2dyZXknLCBsYXMgPSAxKQoKCgpoaXN0KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCduYnBfbG5kX3N1bSddLCBjb2wgPSBoY29sLCBtYWluID0gJ05CUCcsIHhsYWIgPSAnR3RDL3llYXInKQpwb2x5Z29uKHggPSBjKC0xMCwgMTAwLCAxMDAsIC0xMCksIHkgPSBjKDAsIDAsIDEwMDAsIDEwMDApLAogICAgICAgIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpLAogICAgICAgIGJvcmRlciA9IG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpKQoKaGlzdChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbnBwX25saW1fbG5kX3N1bSddLCBjb2wgPSBoY29sICwgbWFpbiA9ICdOUFAnLCB4bGFiID0gJ0d0Qy95ZWFyJykKcG9seWdvbih4ID0gYygzNSwgODAsIDgwLCAzNSksIHkgPSBjKDAsIDAsIDEwMDAsIDEwMDApLAogICAgICAgIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpLAogICAgICAgIGJvcmRlciA9IG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpKQoKCiAgICAgICAgaGlzdChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnY1NvaWxfbG5kX3N1bSddLCBjb2wgPSBoY29sLCBtYWluID0gJ1NvaWwgQ2FyYm9uJywgeGxhYiA9ICdHdEMnKQpwb2x5Z29uKHggPSBjKDc1MCwgMzAwMCwgMzAwMCwgNzUwKSwgeSA9IGMoMCwgMCwgMTAwMCwgMTAwMCksCiAgICAgICAgY29sID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJyksCiAgICAgICAgYm9yZGVyID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJykpCgpoaXN0KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjVmVnX2xuZF9zdW0nXSwgY29sID0gaGNvbCwgbWFpbiA9ICdWZWdldGF0aW9uIENhcmJvbicsIHhsYWIgPSAnR3RDJykKcG9seWdvbih4ID0gYygzMDAsIDgwMCwgODAwLCAzMDApLCB5ID0gYygwLCAwLCAxMDAwLCAxMDAwKSwKICAgICAgICBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSwKICAgICAgIGJvcmRlciA9ICBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSkKCmBgYAoKIyMgVGltZXNlcmllcyB0aGF0IG1hdGNoIHRoZSBjb25zdHJhaW50cy4KUGxvdCB0aGUgb3JpZ2luYWwgZW5zZW1ibGUsIHBsdXMgdGhlIHN0dWZmIHRoYXQgbWF0Y2hlcyB0aGUgY29uc3RyYWludHMuIEluY2x1ZGUgYW5vbWFsaWVzLgoiTGV2ZWwgMiIgY29uc3RyYWludHMgYXJlIGJyb2FkIGNvbnN0cmFpbnRzIHByb2R1Y2VkIGJ5IEFXCiJMZXZlbCAzIiBjb25zdHJhaW50cyBhcmUgdGlnaHRlciBjb25zdHJhaW50cyBmcm9tIGNpdGVhYmxlIHNvdXJjZXMgcHJvZHVjZWQgYnkgRVIuCgpgYGB7ciwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA5fQoKIyByZW1vdmUgdG8gbGV2ZWwgMWEgUmVsYXRpdmUgdG8gdG9wbGV2ZWxfaXgKdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXggPC0odG9wbGV2ZWxfaXhbLVlfbmxldmVsMF9peF0pW2xldmVsMWFfaXhdCgojIFNvIGZ1cnRoZXIgY29uc3RyYWluaW5nIHRvIGxldmVsIDIgY2FuIGJlIGFzc29jaWF0ZWQgYmFjayB0byB0aGUgdG9wIGxldmVsLgoKbGV2ZWwyX2l4ID0gd2hpY2goWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ25icF9sbmRfc3VtJ10gPiAtMTAgJgogICAgICAgICAgICAgICAgICAgIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCducHBfbmxpbV9sbmRfc3VtJ10gPiAzNSAmICBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbnBwX25saW1fbG5kX3N1bSddIDwgODAgJgogICAgICAgICAgICAgICAgICAgIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjU29pbF9sbmRfc3VtJ10gPiA3NTAgJiBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnY1NvaWxfbG5kX3N1bSddIDwgMzAwMCAmCiAgICAgICAgICAgICAgICAgIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjVmVnX2xuZF9zdW0nXSA+IDMwMCAmIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjVmVnX2xuZF9zdW0nXSA8IDgwMAogICkKCgojIDE4MzcgPCBjU29pbCA8IDMyNTcgUGcKIyAzODAgPCBjVmVnIDwgNTM2IFBnCiMgMTAwIDwgZ3BwIDwgMTUwIFBnL3lyCiMgMTMzIDwgblNvaWwgPCAxNTIgUGcKIyBQbHVzIGRlY2FkYWwgcmFuZ2VzIG9mIE5CUCAoMTk2MC0yMDE5KSBmcm9tIC0wLjQgUGcveXIgdG8gKzIuNiBQZy95ciwgd2hlcmUgTkJQIGlzIHRoZSBuZXQgZmx1eCBpbnRvIHRoZSBsYW5kIGluY2x1ZGluZyBsYW5kLXVzZQojIGVtaXNzaW9ucy4KCmxldmVsM19peCA9IHdoaWNoKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCduYnBfbG5kX3N1bSddID4gLTAuNCAmIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCduYnBfbG5kX3N1bSddIDwgMi42ICYKICAgICAgICAgICAgICAgICAgICBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnY1NvaWxfbG5kX3N1bSddID4gMTgzNyAmIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjU29pbF9sbmRfc3VtJ10gPCAzMjU3ICYKICAgICAgICAgICAgICAgICAgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddID4gMzgwICYgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddIDwgNTM2CiAgKQoKCmBgYAoKCldlIGZpbmQgdGhhdCBhZGRpbmcgYSBjb25zdHJhaW50IHRvIGxldmVsIDIgY29uc3RyYWlucyB0aGUgYmVoYXZpb3VyIG9mIHRoZSBzb2lsIGNhcmJvbiBwb29sLCBidXQgbm90IHRoZSB2ZWdldGF0aW9uIGNhcmJvbiBwb29sLiBQcm9iYWJseSBub3QgYSBzdXJwcmlzZSwgZ2l2ZW4gdGhlIFNvaWwgQ2FyYm9uIHBvb2wgKGFuZCBjaGFuZ2VzKSBhcmUgbXVjaCBsYXJnZXIgdGhhbiB0aGUgdmVnZXRhdGlvbiBjYXJib24gcG9vbC4KCmBgYHtyIHZlZ0Mtc29pbEMtY29uc3RyYWluZWQsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gOH0KI2NTb2lsX2Vuc19hbm9tIFt0b3BsZXZlbF90b19sZXZlbF8xYV9peCwgXQoKcGFyKG1mcm93PSBjKDEsNCksIGxhcyA9IDEpCgpwbG90Y29sIDwtIGMobWFrZVRyYW5zcGFyZW50KCdibGFjaycsIDcwKSkKb3ZlcnBsb3Rjb2wgPC0gYyhtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzMnLCAyMDApKQoKCnlsaW0gPSByYW5nZShjU29pbF9lbnMpCm1hdHBsb3QoeWVhcnMsIHQoY1NvaWxfZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnY1NvaWwnLAogICAgICAgIGJ0eSA9ICduJykKbWF0bGluZXMoIHllYXJzLCB0KChjU29pbF9lbnNbdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXgsIF0pW2xldmVsMl9peCwgXSksY29sID0gb3ZlcnBsb3Rjb2wsICBsd2QgPSAxLjUsIGx0eSA9ICdzb2xpZCcpCgp5bGltID0gcmFuZ2UoY1NvaWxfZW5zKQptYXRwbG90KHllYXJzLCB0KGNWZWdfZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwKICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnY1ZlZycsCiAgICAgICAgYnR5ID0gJ24nKQptYXRsaW5lcyggeWVhcnMsIHQoKGNWZWdfZW5zW3RvcGxldmVsX3RvX2xldmVsXzFhX2l4LCBdKVtsZXZlbDJfaXgsIF0pLCBjb2wgPSBvdmVycGxvdGNvbCwgbHdkID0gMS41LCBsdHkgPSAnc29saWQnKQoKCgp5bGltID0gcmFuZ2UoY1NvaWxfZW5zX2Fub20pCm1hdHBsb3QoeWVhcnMsIHQoY1NvaWxfZW5zX2Fub20pLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdjU29pbCBBbm9tYWx5JywKICAgICAgICBidHkgPSAnbicpCm1hdGxpbmVzKCB5ZWFycywgdCgoY1NvaWxfZW5zX2Fub21bdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXgsIF0pW2xldmVsMl9peCwgXSksY29sID0gb3ZlcnBsb3Rjb2wsIGx3ZCA9IDEuNSwgbHR5ID0gJ3NvbGlkJykKCgp5bGltID0gcmFuZ2UoY1NvaWxfZW5zX2Fub20pCm1hdHBsb3QoeWVhcnMsIHQoY1ZlZ19lbnNfYW5vbSksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IHlsaW0sIGNvbCA9IHBsb3Rjb2wsCiAgICAgICAgeWxhYiA9ICdHdEMnLCBtYWluID0gJ2NWZWcgQW5vbWFseScsCiAgICAgICAgYnR5ID0gJ24nKQptYXRsaW5lcyggeWVhcnMsIHQoKGNWZWdfZW5zX2Fub21bdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXgsIF0pW2xldmVsMl9peCwgXSksY29sID0gb3ZlcnBsb3Rjb2wsbHdkID0gMS41LCBsdHkgPSAnc29saWQnKQoKYGBgCgojIyBBdG1vc3BoZXJpYyBncm93dGgKV2UgY2FuIGNhbGN1bGF0ZWQgdGhlIGF0bW9zcGhlcmljIGdyb3d0aCBhcyBGb3NzaWwgZnVsZSBlbWlzc2lvbnMgKEdDQikgLSBPY2VhbiB1cHRha2UgIChHQ0IpIC0gbmV0IGxhbmQgZmx1eCAoSlVMRVMgTkJQKQoKQ29udmVyc2VseSwgd2UgY2FuIGNhbGN1bGF0ZSB0aGUgbGFuZCB1cHRha2UgYXMgTkJQID0gRkYgLSBvY2VhbiAtIGFnIChEbyB3ZSBoYXZlIEFHIGluIEpVTEVTPykKCmBgYHtyfQoKcmVzaWQgPC0gaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBvY2VhbiBzaW5rYCAtIGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRgZm9zc2lsIGVtaXNzaW9ucyBleGNsdWRpbmcgY2FyYm9uYXRpb25gCgpyZXNpZF9peCA8LSB3aGljaChoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciAlaW4lIHllYXJzKQoKbmVnX2FnIDwtIHN3ZWVwKG5icF9lbnMsIDIsIHJlc2lkW3Jlc2lkX2l4XSwgRlVOID0gJysnKQoKCm1hdHBsb3QoeWVhcnMsIHQoLW5lZ19hZyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IGMoMCwgOCksIGNvbCA9IHBsb3Rjb2wsIAogICAgICAgICB5bGFiID0gJ0d0QycsIG1haW4gPSAnYXRtb3NwaGVyaWMgZ3Jvd3RoJywgeGxhYiA9ICcnLAogICAgICAgICBidHkgPSAnbicsIHhsaW0gPSBjKDE5NjAsIDIwMjApKQoKbGluZXMoaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JFllYXIsIGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRgYXRtb3NwaGVyaWMgZ3Jvd3RoYCwgY29sID0gJ3JlZCcpCgoKYGBgCgoKIyMjIGFub3RoZXIgd2F5IHRvIGNhbGNsdWxhdGUgYXRtb3NwaGVyaWMgZ3Jvd3RoCgpUaGVzZSB0d28gbWV0aG9kcyBnaXZlIHZlcnkgc2ltaWxhciBvdXRjb21lcywgYmFyIGFuIG91dGxpZXIuCgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDd9CgphZyA8LSBtYXRyaXgobnJvdyA9IG5yb3cobmJwX2VucyksIG5jb2wgPSBuY29sKG5icF9lbnMpKQpmb3IoaSBpbiAxOm5yb3cobmJwX2VucykpewogIAogIGFnW2ksIF0gPC0gaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBmb3NzaWwgZW1pc3Npb25zIGV4Y2x1ZGluZyBjYXJib25hdGlvbmBbcmVzaWRfaXhdIC0gaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBvY2VhbiBzaW5rYFtyZXNpZF9peF0gLSAgbmJwX2Vuc1tpLCBdCiAgCn0KCnBkZih3aWR0aCA9IDgsIGhlaWdodCA9IDYsIGZpbGUgPSAnYWcucGRmJykKbWF0cGxvdCh5ZWFycywgdChhZyksIHR5cGUgPSAnbCcsIGx0eSA9ICdzb2xpZCcseWxpbSA9IGMoMCwgOCksIGNvbCA9ICdkYXJrcmVkJywgCiAgICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdhdG1vc3BoZXJpYyBncm93dGgnLCB4bGFiID0gJycsCiAgICAgICAgIGJ0eSA9ICduJywgeGxpbSA9IGMoMTk2MCwgMjAyMCkpCgpsaW5lcyhoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciwgaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBhdG1vc3BoZXJpYyBncm93dGhgLCBjb2wgPSAnYmxhY2snLCBsd2QgPTIpCmRldi5vZmYoKQoKYGBgCgoKCiMjIFRvdGFsIGxhbmQgY2FyYm9uIGNoYW5nZSAoaW5jb3JyZWN0KQoKV2UgcGxvdCB0aGUgSlVMRVMgdG90YWwgbGFuZCBjYXJib24gY2hhbmdlIGZyb20gMTg1MCwgdG9nZXRoZXIgd2l0aCAib2JzZXJ2YXRpb25zIiBmcm9tIHRoZSBHbG9iYWwgQ2FyYm9uIEJ1ZGdldCAoRnJpZWRsaWdzdGVpbiBldCBhbCwgMjAyMCkuIFRoZSAib2JzZXJ2YXRpb25zIGFyZSB0aGUgY3VtdWxhdGl2ZSBzdW0gb2YgdGhlICdsYW5kIHNpbmsnIGNvbHVtbiBvbiB0aGUgImhpc3RvcmljYWwgb2JzZXJ2YXRpb25zIHRhYiBvZiB0aGUgZGF0YSBmcm9tIHRoZSBwYXBlci4gSXQgc3RhdGVzICJUaGUgbGFuZCBzaW5rIGlzIHRoZSBhdmVyYWdlIG9mIHNldmVyYWwgZHluYW1pYyBnbG9iYWwgdmVnZXRhdGlvbiBtb2RlbHMgdGhhdCByZXByb2R1Y2UgdGhlIG9ic2VydmVkIG1lYW4gdG90YWwgbGFuZCBzaW5rIG9mIHRoZSAxOTkwcy4iCgpgYGB7ciB0b3RhbC1sYW5kLWNhcmJvbi1jaGFuZ2UsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gOH0KIyBUaGlzIGNhbGN1bGF0ZXMgdG90YWwgbGFuZCBjYXJib24gaW5jb3JyZWN0bHkKCnBhcihtZnJvdz0gYygxLDIpLCBsYXMgPSAxKQoKeWxpbSA9IHJhbmdlKHRvdGFsX2xhbmRfY2FyYm9uX2VucykKbWF0cGxvdCh5ZWFycywgdCh0b3RhbF9sYW5kX2NhcmJvbl9lbnMpLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdUb3RhbCBsYW5kIGNhcmJvbicsCiAgICAgICAgYnR5ID0gJ24nKQptYXRsaW5lcyggeWVhcnMsIHQoKHRvdGFsX2xhbmRfY2FyYm9uX2Vuc1t0b3BsZXZlbF90b19sZXZlbF8xYV9peCwgXSlbbGV2ZWwyX2l4LCBdKSwgY29sID0gb3ZlcnBsb3Rjb2wsIGx0eSA9ICdzb2xpZCcsIGx3ZCA9IDEuNSkKCnlsaW0gPSByYW5nZSh0b3RhbF9sYW5kX2NhcmJvbl9hbm9tKQptYXRwbG90KHllYXJzLCB0KHRvdGFsX2xhbmRfY2FyYm9uX2Fub20pLCB0eXBlID0gJ2wnLCBsdHkgPSAnc29saWQnLHlsaW0gPSB5bGltLCBjb2wgPSBwbG90Y29sLAogICAgICAgIHlsYWIgPSAnR3RDJywgbWFpbiA9ICdUb3RhbCBsYW5kIGNhcmJvbiBhbm9tYWx5JywKICAgICAgICBidHkgPSAnbicpCm1hdGxpbmVzKCB5ZWFycywgdCgodG90YWxfbGFuZF9jYXJib25fYW5vbVt0b3BsZXZlbF90b19sZXZlbF8xYV9peCwgXSlbbGV2ZWwyX2l4LCBdKSwgY29sID0gb3ZlcnBsb3Rjb2wsIGx0eSA9ICdzb2xpZCcsIGx3ZCA9IDEuNSkKCiNBbm9tYWxpemUgaGlzdG9yaWNhbCBvYnNlcnZhdGlvbnMgdG8gMTg1MCAtIDE4NzAKaGlzdG9yaWNhbF90b3RhbF9sYW5kX2NhcmJvbl9vYnMgPC0gY3Vtc3VtKGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRgbGFuZCBzaW5rYCkKaGlzdG9yaWNhbF90b3RhbF9sYW5kX2NhcmJvbl9vYnNfYW5vbSA8LSBoaXN0b3JpY2FsX3RvdGFsX2xhbmRfY2FyYm9uX29icyAtIGhpc3RvcmljYWxfdG90YWxfbGFuZF9jYXJib25fb2JzW3doaWNoKGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyICVpbiUgMTg1MDoxODcwKV0KCmxpbmVzKGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyLGhpc3RvcmljYWxfdG90YWxfbGFuZF9jYXJib25fb2JzX2Fub20sIHR5cGUgPSAnbCcsY29sID0gJ2JsdWUnLCBsd2QgPSAyKQpsZWdlbmQoJ3RvcGxlZnQnLCBsZWdlbmQgPSBjKCdSdWxlZCBvdXQnLCAnTGV2ZWwxYSBjb25zdHJhaW50JywgJ2hpc3RvcmljYWwnKSwgY29sID0gYygnYmxhY2snLCBvdmVycGxvdGNvbCwgJ2JsdWUnKSwKICAgICAgIGx3ZCA9IGMoMSwxLjUsMiksIGx0eSA9ICdzb2xpZCcpCgoKYGBgCgojIyMgTGFuZCBjYXJib24gU2luaz8KCkkgdGhpbmsgdG8gbWFrZSBhIGZhaXIgY29tcGFyaXNvbiwgd2UgbWlnaHQgbmVlZCB0byB0YWtlIHRoZSBkaWZmIG9mIHRoZSBhbm9tYWx5IChvciBqdXN0IHRoZSB0aW1lc2VyaWVzKSwgYXMgdGhlIGFib3ZlIHJlcHJlc2VudHMgdGhlIHRvdGFsIGNoYW5nZSBzaW5jZSAxODUwLCBhbmQgSSB0aGluayBhbGwgdGhlICJsYW5kIHNpbmsiIHN0dWZmIGxvb2tzIGF0IHRoZSB5ZWFyLXRvLXllYXIgY2hhbmdlcy4KCmBgYHtyIHRvdGFsLWxhbmQtY2FyYm9uLXNpbmssIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQoKCmxhbmRzaW5rX2VucyA8LSBtYXRyaXgoTkEsIG5yb3cgPSBucm93KHRvdGFsX2xhbmRfY2FyYm9uX2VucyksIG5jb2wgPSBuY29sKHRvdGFsX2xhbmRfY2FyYm9uX2VucyktMSkKCmZvcihpIGluIDE6bnJvdyhsYW5kc2lua19lbnMpKXsKICAKICBsYW5kc2lua19lbnNbaSwgXSA8LSBkaWZmKHRvdGFsX2xhbmRfY2FyYm9uX2Vuc1tpLCBdKQp9CgoKeWxpbSA9IHJhbmdlKGxhbmRzaW5rX2VucykKbWF0cGxvdCh5ZWFyc1stMV0sIHQobGFuZHNpbmtfZW5zKSwgdHlwZSA9ICdsJywgbHR5ID0gJ3NvbGlkJyx5bGltID0geWxpbSwgY29sID0gcGxvdGNvbCwgeGxhYiA9ICcnLAogICAgICAgIHlsYWIgPSAnR3RDL3llYXInLCBtYWluID0gJ1RvdGFsIGxhbmQgY2FyYm9uIHNpbmsnLAogICAgICAgIGJ0eSA9ICduJykKbWF0bGluZXMoIHllYXJzWy0xXSwgdCgobGFuZHNpbmtfZW5zW3RvcGxldmVsX3RvX2xldmVsXzFhX2l4LCBdKVtsZXZlbDJfaXgsIF0pLCBjb2wgPSAndG9tYXRvMycsIGx0eSA9ICdzb2xpZCcpCgpsaW5lcyhoaXN0b3JpY2FsX2NhcmJvbl9idWRnZXQkWWVhciwgaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBsYW5kIHNpbmtgLCBjb2wgPSAnYmx1ZScsIGx3ZCA9IDIsIHhsYWIgPSAnJykKbGVnZW5kKCdib3R0b21sZWZ0JywgbGVnZW5kID0gYygnUnVsZWQgb3V0JywnbGV2ZWwgMWEgY29uc3RyYWluZWQnLCdoaXN0b3JpY2FsJyksIGNvbCA9IGMoJ2JsYWNrJywndG9tYXRvMycsICdibHVlJyApLCBsdHkgPSdzb2xpZCcsCiAgICAgICBsd2QgPSBjKDEsMSwyKSkKCgpgYGAKCgojIyMgSWRlbnRpZnkgcGFydHMgb2YgcGFyYW1ldGVyIHNwYWNlIHdoZXJlIHRoZSBsYW5kIGNhcmJvbiBzaW5rIGlzIGF0IGl0cyBtYXhpbXVtCldoYXQgZG8gdGhlc2UgcGFydHMgb2YgcGFyYW1ldGVyIHNwYWNlIHRlbGwgdXMgYWJvdXQgd2hhdCB3ZSBuZWVkIHRvIGRvIHRvIGhhdmUgdGhlIG1vZGVsIHJlcHJvZHVjZSByZWFsaXR5PwpgYGB7cn0KCiMgQnVpbGQgYW4gZW11bGF0b3IgZm9yIHRvdGFsIGxhbmQgY2FyYm9uIHVwdGFrZSBhdCB0aGUgZW5kIG9mIHRoZSBjZW50dXJ5CgoKIyBlbnNlbWJsZSBvZiBtb2Rlcm4gbGFuZHNpbmsKbGFuZHNpbmtfbW9kZXJuX2l4IDwtIHdoaWNoKHllYXJzWy0xXSAlaW4lIDE5OTQ6MjAxMykKCmxhbmRzaW5rX21vZGVybl9lbnMgPC0gKGFwcGx5KGxhbmRzaW5rX2Vuc1ssIGxhbmRzaW5rX21vZGVybl9peF0sIDEsIG1lYW4pKQoKbGFuZHNpbmtfbW9kZXJuX2Vuc19sZXZlbDFhIDwtIGxhbmRzaW5rX21vZGVybl9lbnNbdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXhdCgojIG9ic2VydmF0aW9ucyBvZiBtb2Rlcm4gbGFuZCBzaW5rCgpoaXN0X2l4IDwtIHdoaWNoKGhpc3RvcmljYWxfY2FyYm9uX2J1ZGdldCRZZWFyICVpbiUgMTk5NDoyMDEzKQpsYW5kc2lua19tb2Rlcm5fb2JzIDwtIG1lYW4oaGlzdG9yaWNhbF9jYXJib25fYnVkZ2V0JGBsYW5kIHNpbmtgW2hpc3RfaXggXSkKCiMgVGhpcyBpcyBhbGwgNDk5IG1lbWJlcnMKbGFuZHNpbmtfbW9kZXJuX2VyciA8LSBsYW5kc2lua19tb2Rlcm5fZW5zIC0gbGFuZHNpbmtfbW9kZXJuX29icwoKbGFuZHNpbmtfbW9kZXJuX2Vycl9sZXZlbDFhIDwtIGxhbmRzaW5rX21vZGVybl9lcnJbdG9wbGV2ZWxfdG9fbGV2ZWxfMWFfaXhdIwoKCgojW2xldmVsMl9peCwgXQoKIyBCdWlsZCBlbXVsYXRvcnMgCgojIElkZW50aWZ5IHRoZSBwYXJ0cyBvZiBwYXJhbWV0ZXIgc3BhY2Ugd2hlcmUgdGhlIGRpZmZlcmVuY2VzIGFyZSBsb3cKCgojIEFyZSB3ZSBnZXR0aW5nIGNsb3NlIGZvciB0aGUgcmlnaHQgcmVhc29ucz8gV2hhdCBlbHNlIGlzIGdvaW5nIHdyb25nPwoKCgoKYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNn0KCgpwYXIobWZyb3cgPSBjKDQsOCksIG1hciA9IGMoMywyLDIsMSkpCmZvcihpIGluIDE6ZCl7CiAgCiAgcGxvdChYX2xldmVsMWFbLCBpXSxsYW5kc2lua19tb2Rlcm5fZXJyX2xldmVsMWEsICkKICAKfQoKCmBgYAoKYGBge3IsIHJlc3VsdHMgPSAnaGlkZSd9CiAgCgpmaXRfbGFuZHNpbmtfZXJyIDwtIGttKH4uLGRlc2lnbiA9IFhfbGV2ZWwxYSwgcmVzcG9uc2UgPSAgbGFuZHNpbmtfbW9kZXJuX2Vycl9sZXZlbDFhKQoKCmBgYApgYGB7ciwgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDh9CgpwbG90KGZpdF9sYW5kc2lua19lcnIpCgpgYGAKCiMjIyB3aGF0IHBhcnRzIG9mIHBhcmFtZXRlciBzcGFjZSBhcmUgdGhlIGNsb3Nlc3Q/CmBgYHtyfQoKIyBUd28gc3RyYXRlZ2llcyAtIHBsb3QgbGFuZCBzaW5rIGVycm9yIGFnYWluc3QgcGFyYW1ldGVycywgYW5kIGlkZW50aWZ5IGJpdHMgb2YgcGFyYW1ldGVyIHNwYWNlIHdpdGggc21hbGxlc3QgZXJyb3IKCiNsb3dfZXJyb3JfaXggPC0gbGFuZHNpbmtfbW9kZXJuX2Vycl9sZXZlbDFhCgoKbWlucyA8LSBhcHBseShYX2xldmVsMWEsMixGVU4gPSBtaW4pCm1heGVzIDwtIGFwcGx5KFhfbGV2ZWwxYSwyLEZVTiA9IG1heCkKICAKbnNhbXBfdW5pZiA8LSAxMDAwMDAgIApYX3VuaWYgPC0gc2FtcF91bmlmKG5zYW1wX3VuaWYsIG1pbnMgPSBtaW5zLCBtYXhlcyA9IG1heGVzKQoKcHJlZF91bmlmIDwtIHByZWRpY3QoZml0X2xhbmRzaW5rX2VyciwgbmV3ZGF0YSA9IFhfdW5pZiwgdHlwZSA9ICdVSycpCgpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDEyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CgoKcGFyKG9tYSA9IGMoMCwwLDAsMyksIGJnID0gJ3doaXRlJykKcGFpcnMoWF9sZXZlbDFhLAogICAgICBsYWJlbHMgPSAxOmQsCiAgICAgIGdhcCA9IDAsIGxvd2VyLnBhbmVsID0gTlVMTCwgeGxpbSA9IGMoMCwxKSwgeWxpbSA9IGMoMCwxKSwKICAgICAgcGFuZWwgPSBjcG9pbnRzLAogICAgICB6PSBsYW5kc2lua19tb2Rlcm5fZW5zX2xldmVsMWEsCiAgICAgIGNvbCA9IGJ5ciwKICAgICAgY2V4LmxhYmVscyA9IDEsCiAgICAgIGNvbC5heGlzID0gJ3doaXRlJywKICAgICAgcGNoID0gMjAKICAgICAgKQoKI2ltYWdlLnBsb3QobGVnZW5kLm9ubHkgPSBUUlVFLAojICAgICAgICAgICB6bGltID0gYygwLDEpLAojICAgICAgICAgICBjb2wgPSBibHVlcywKIyAgICAgICAgICAgbGVnZW5kLmFyZ3MgPSBsaXN0KHRleHQgPSAnRGVuc2l0eSBvZiBtb2RlbCBydW5zIG1hdGNoaW5nIHRoZSBjcml0ZXJpYScsIHNpZGUgPSAzLCBsaW5lID0gMSksCiMgICAgICAgICAgIGhvcml6b250YWwgPSBUUlVFCiMpCgojICBsZWdlbmQoJ2xlZnQnLCBsZWdlbmQgPSBwYXN0ZSgxOmQsIGNvbG5hbWVzKGxocykpLCBjZXggPSAwLjksIGJ0eSA9ICduJykKCgpgYGAKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSAxMn0KCgpYX2tlcHQgPC0gWF91bmlmW2FicyhwcmVkX3VuaWYkbWVhbikgPCAxLCBdIAoKcGFyKG9tYSA9IGMoMCwwLDAsMyksIGJnID0gJ3doaXRlJykKcGFpcnMoWF9rZXB0LAogICAgICBsYWJlbHMgPSAxOmQsCiAgICAgIGdhcCA9IDAsIGxvd2VyLnBhbmVsID0gTlVMTCwgeGxpbSA9IGMoMCwxKSwgeWxpbSA9IGMoMCwxKSwKICAgICAgcGFuZWwgPSBkZnVuY191cCwKICAgICAgY2V4LmxhYmVscyA9IDEsCiAgICAgIGNvbC5heGlzID0gJ3doaXRlJywKICAgICAgZGZ1bmMuY29sID0gYmx1ZXMpCgppbWFnZS5wbG90KGxlZ2VuZC5vbmx5ID0gVFJVRSwKICAgICAgICAgICB6bGltID0gYygwLDEpLAogICAgICAgICAgIGNvbCA9IGJsdWVzLAogICAgICAgICAgIGxlZ2VuZC5hcmdzID0gbGlzdCh0ZXh0ID0gJ0RlbnNpdHkgb2YgbW9kZWwgcnVucyBtYXRjaGluZyB0aGUgY3JpdGVyaWEnLCBzaWRlID0gMywgbGluZSA9IDEpLAogICAgICAgICAgIGhvcml6b250YWwgPSBUUlVFCikKCmxlZ2VuZCgnbGVmdCcsIGxlZ2VuZCA9IHBhc3RlKDE6ZCwgY29sbmFtZXMobGhzKSksIGNleCA9IDAuOSwgYnR5ID0gJ24nKQoKCgoKCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNn0KCnBhcihtZnJvdyA9IGMoNCw4KSwgbWFyID0gYygzLDIsMiwxKSkKCmZvcihpIGluIDE6ZCl7CiAgCiAgaGlzdChYX2tlcHRbLCBpXSwgY29sID0gJ2dyZXknLCBib3JkZXIgPSAnd2hpdGUnLCAKICAgICAgICB4bGltID0gYygwLDEpLCBicmVha3MgPSBzZXEoZnJvbSA9IDAsIHRvID0gMSwgYnkgPSAwLjEpLAogICAgICAgbWFpbiA9IGNvbG5hbWVzKFhfa2VwdClbaV0pCiAgCn0KCgpgYGAKCgoKIyMgQXVnbWVudCB0aGUgZGVzaWduLgpUaGUgZnVuY3Rpb24gYWRkTnJveURlc2lnblBvaW50cyBidWlsZHMgYW4gZW11bGF0b3IgZm9yIGVhY2ggbW9kZWwgb3V0cHV0IGluIFkuIEl0IGNvbXBhcmVzIHRoZSBvdXRwdXQgb2YgZWFjaCBlbXVsYXRvciBhdCBhIG51bWJlciBvZiBjYW5kaWRhdGUgZGVzaW4gcG9pbnRzLCBhbmQgY2hvb3NlcyBhIHNwYWNlLWZpbGxpbmcgc2V0IG9mIHRoZW0gdGhhdCB0aGF0IGFyZSBOb3QgUnVsZWQgT3V0IFlldCAoc3RhdGlzdGljYWxseSBjbG9zZSB0byB0aGUgb2JzZXJ2YXRpb24gYXQgWV90YXJnZXQpLgoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQojIEZpbmFsIG91dHB1dCBuZWVkcyB0byBiZSBleHByZXNzZWQgaW4gdGVybXMgb2Ygb3JpZ2luYWwgTEhTLCB0aGVuIHB1dCBiYWNrIG91dCB0byBjb25mIGZpbGVzLgoKIyBUaGlzIGZ1bmN0aW9uIGFkZHMgbi5hdWcgcG90ZW50aWFsIGRlc2lnbiBwb2ludHMsIGFuZCBmaW5kcyB0aGVpciBpbXBsYXVzaWJpbGl0eQojIHNjb3JlIGluIFgubnJveQoKd2F2ZTEgPSBhZGROcm95RGVzaWduUG9pbnRzKFggPSBYX2xldmVsMWEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgWSA9IFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgWV90YXJnZXQgPSBZX3RhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fYXVnID0gNTAwMDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluc19hdWcgPSBtaW5zX2F1ZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heGVzX2F1ZyA9IG1heGVzX2F1ZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVzID0gMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2NfbGlzdD1kaXNjX2xpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNjX3NkX2xpc3QgPSBkaXNjX3NkX2xpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNfc2RfbGlzdCA9IG9ic19zZF9saXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9hcHAgPSA1MDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBucmVwcyA9IDUwMCkKYGBgCgoKCgojIyBXcml0ZSB0aGUgYXVnbWVudGVkIGRlc2lnbgpUaGUgZnVuY3Rpb24gd3JpdGVfanVsZXNfZGVzaWduIGhlcmUgc2ltcGx5IHRha2VzIHRoZSBwb2ludHMgY2FsY3VsYXRlZCBieSBhZGROcm95RGVzaWduUG9pbnRzIGFuZCB3cml0ZXMgdGhlbSB0byBjb25maWd1cmF0aW9uIGZpbGVzLgoKYGBge3J9CgojIHRoaXMgbmVlZHMgc29ydGluZwpzb3VyY2UoJ34vbXlScGFja2FnZXMvanVsZXNSL3ZpZ25ldHRlcy9kZWZhdWx0X2p1bGVzX3BhcmFtZXRlcl9wZXJ0dXJiYXRpb25zLlInKQoKIyBFYXNpZXN0IHdheSB0byBnZW5lcmF0ZSBhIGRlc2lnbiBvZiB0aGUgcmlnaHQgc2l6ZSBpcyB0byBoYXZlIGEgImZhYyIgd2hpY2ggdGFrZXMKIyB0aGUgbmFtZXMgZnJvbSB0aGUgcGFyYW1ldGVyIGxpc3QsIGFuZCB0aGVuIG11bHRpcGxpZXMgZXZlcnl0aGluZyBieSAwLjUgb3IgMgoKdGYgPC0gJ2xfdmdfc29pbCcKIyB3ZSBkb24ndCB3YW50IGFueXRoaW5nIHRoYXQgaXMgVFJVRS9GQUxTRSB0byBiZSBpbiBmYWMKZmFjX2luaXQgPC0gbmFtZXMocGFyYW1saXN0KQpub3RfdGZfaXggPC0gd2hpY2gobmFtZXMocGFyYW1saXN0KSE9dGYpCnBhcmFtbGlzdF90cnVuYyA8LXBhcmFtbGlzdFtub3RfdGZfaXhdCgpmYWMgPC0gbmFtZXMocGFyYW1saXN0X3RydW5jKQoKbWF4ZmFjIDwtbGFwcGx5KHBhcmFtbGlzdF90cnVuYyxmdW5jdGlvbih4KSB4JG1heFt3aGljaC5tYXgoeCRtYXgpXSAvIHgkc3RhbmRhcmRbd2hpY2gubWF4KHgkbWF4KV0pCm1pbmZhYyA8LSBsYXBwbHkocGFyYW1saXN0X3RydW5jLGZ1bmN0aW9uKHgpIHgkbWluW3doaWNoLm1heCh4JG1heCldIC8geCRzdGFuZGFyZFt3aGljaC5tYXgoeCRtYXgpXSkKCgpgYGAKCgpgYGB7cn0KIyBjcmVhdGUgYSBkaXJlY3RvcnkgZm9yIHRoZSBjb25maWd1cmF0aW9uIGZpbGVzCmNvbmZkaXIgPC0gJ2NvbmZfZmlsZXNfYXVnbWVudF9KVUxFUy1FUy0xcDAnCgpkaXIuY3JlYXRlKGNvbmZkaXIpCgpYX21tIDwtIHdhdmUxJFhfbW0KCiMgVGhpcyBpcyB0aGUgZnVuY3Rpb24gdGhhdCB3cml0ZXMgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZXMuCndyaXRlX2p1bGVzX2Rlc2lnbihYX21tID0gWF9tbSwgcGFyYW1saXN0PXBhcmFtbGlzdCwgbiA9IG5yb3coWF9tbSksCiAgICAgICAgICAgICAgICAgICAgZmFjID0gZmFjLCBtaW5mYWMgPSBtaW5mYWMsIG1heGZhYyA9IG1heGZhYywKICAgICAgICAgICAgICAgICAgICB0ZiA9IHRmLAogICAgICAgICAgICAgICAgICAgIGZucHJlZml4ID0gcGFzdGUwKGNvbmZkaXIsJy9wYXJhbS1wZXJ0dXJiLVAnKSwKICAgICAgICAgICAgICAgICAgICBsaHNmbiA9IHBhc3RlMChjb25mZGlyLCcvbGhzX2V4YW1wbGUudHh0JyksCiAgICAgICAgICAgICAgICAgICAgc3RhbmZuID0gcGFzdGUwKGNvbmZkaXIsJy9zdGFucGFybXNfZXhhbXBsZS50eHQnKSwKICAgICAgICAgICAgICAgICAgICBhbGxzdGFuZm4gPSBwYXN0ZTAoY29uZmRpciwnL2FsbHN0YW5wYXJtc19leGFtcGxlLnR4dCcpLAogICAgICAgICAgICAgICAgICAgIHJuID0gMTIsCiAgICAgICAgICAgICAgICAgICAgc3RhcnRudW0gPSA1MDApCmBgYAoKIyMgQ2hlY2sgdGhlIGRlc2lnbgpDaGVjayB0aGF0IHRoZSBhdWdtZW50ZWQgZGVzaWduIHByb2R1Y2VzIHdoYXQgd2UgZXhwZWN0LiBOZXcgZW5zZW1ibGUgbWVtYmVycyBzaG91bGQgYmUgc29tZXdoYXQgY29uc3RyYWluZWQgd2l0aGluIHRoZSBib3VuZGFyaWVzIG9mIHRoZSBvcmlnaW5hbCBkZXNpZ24sIGlmIHRoZSBjb21wYXJpc29uIHRvIGRhdGEgb2ZmZXJzIGFueSBjb25zdHJhaW50LgoKYGBge3IsIGZpZy53aWR0aCA9IDE1LCBmaWcuaGVpZ2h0ID0gMTV9CgoKWF9tbSA8LSB3YXZlMSRYX21tCgpwYWlycyhyYmluZChYLCBYX21tKSwgeGxpbSA9IGMoMCwxKSwgeWxpbSA9IGMoMCwxKSwgZ2FwID0gMCwgbG93ZXIucGFuZWwgPSBOVUxMLCAKICAgICAgY29sID0gYyhyZXAoJ2dyZXknLCBucm93KFgpKSwgcmVwKCdyZWQnLCBucm93KFhfbW0pKSksCiAgICAgIHBjaCA9IGMocmVwKDIxLCBucm93KFgpKSwgcmVwKDIwLCBucm93KFhfbW0pKSkKICAgICAgKQoKcGFyKHhwZCA9IE5BKQoKbGVnZW5kKCdib3R0b20nLAogICAgICAgbGVnZW5kID0gYygnT3JpZ2luYWwgZGVzaWduJywgJ05ldyBwb2ludHMnKSwKICAgICAgIGNvbCA9IGMoJ2dyZXknLCAncmVkJyksCiAgICAgICBpbnNldCA9IDAuMTUsCiAgICAgICBjZXggPSAxLjUsCiAgICAgICBwY2ggPSBjKDIxLDIwKQopCgpgYGAKCgpWaXN1YWxpc2UgdGhlIHByZWRpY3RlZCBvdXRwdXRzIGF0IHRoZSBOUk9ZIHBvaW50cyBvZiB0aGUgb2xkIGRlc2lnbiwgYW5kIHRoZSBuZXcgc3VnZ2VzdGVkIGRlc2lnbi4KYGBge3J9CllfbW1fbGlzdCA8LSB2ZWN0b3IobW9kZSA9J2xpc3QnLCBsZW5ndGggPSBsZW5ndGgod2F2ZTEkZml0X2xpc3QpKQoKZm9yKGkgaW4gMTpsZW5ndGgod2F2ZTEkZml0X2xpc3QpKXsKCnlfbW0gPC0gcHJlZGljdChvYmplY3Q9d2F2ZTEkZml0X2xpc3RbW2ldXSwgbmV3ZGF0YSA9IHdhdmUxJFhfbW0sIHR5cGUgPSAnVUsnKQoKWV9tbV9saXN0W1tpXV0gPC0geV9tbQoKfQpgYGAKCiMjIFZpc3VhbGlzaW5nIHRoZSBlbXVsYXRlZCBvdXRwdXRzIGF0IHRoZSBwcm9wb3NlZCBuZXcgZGVzaWduIHBvaW50cy4KCkludGVyZXN0aW5nbHksIHRoZXNlIGFyZW4ndCBwZXJmZWN0bHkgd2l0aGluIHRoZSBvcmlnaW5hbCBoYXJkIGJvdW5kYXJpZXMgc2V0IGJ5IEFuZHksIGV2ZW4gdGhvdWdoIEkndmUgc2V0IHRob3NlIGJvdW5kYXJpZXMgdG8gYmUgdGhlICstIDQgc3RhbmRhcmQgZGV2aWF0aW9uIHRocmVob2xkcyBpbiB0aGUgSGlzdG9yeSBNYXRjaC4gSSBzdWdnZXN0IHRoaXMgaXMgYmVjYXVzZSB0aGVyZSBpcyBtb2RlbCBkaXNjcmVwYW5jeSwgYW5kIHRoYXQgdGhlcmUgaXMgY29uc2lkZXJhYmxlIHdyaWdnbGUgcm9vbSBpbmR1Y2VkIGZyb20gZW11bGF0b3IgdW5jZXJ0YWludHkuCgpJbiBwYXJ0aWN1bGFyLCBpdCBhcHBlYXJzIHRoYXQgdmVnZXRhdGlvbiBjYXJib24gaXMgZGlmZmljdWx0IHRvIGtlZXAgaGlnaCwgYW5kIHRoYXQgbWFueSBOUk9ZIHByb3Bvc2VkIG1lbWJlcnMgaGF2ZSBhIGZhaXJseSBsb3cgdmVnZXRhdGlvbiBjYXJib24uIFRoaXMgbWlnaHQgbmVlZCBhIGRpc2NyZXBhbmN5IHRlcm0sIG9yIGFkanVzdGluZyBpbiBzb21lIG90aGVyIHdheS4gSXQgY2VydGFpbmx5IG5lZWRzIGV4cGxvcmluZywgYW5kIGEgT0FBVCBwbG90IG1pZ2h0IGdpdmUgY2x1ZXMgYXMgdG8gdGhlIHBhcmFtZXRlcnMgdG8gY2hvb3NlLgoKYGBge3IsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gMTB9CiMgSGlzdG9ncmFtIG9mIGxldmVsIDEgY29uc3RyYWludHMKaGNvbCA9ICdkYXJrZ3JleScKbGNvbCA9ICdibGFjaycKcGFyKG1mcm93ID0gYygyLDIpLCBmZyA9ICdkYXJrZ3JleScsIGxhcyA9IDEpCgpkaXNjc2QgPC0gYyhkaXNjX3NkX2xpc3QsIHJlY3Vyc2l2ZSA9IFRSVUUpCgpoaXN0KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCduYnBfbG5kX3N1bSddLCBjb2wgPSBoY29sLCBtYWluID0gJ05CUCcsIHhsYWIgPSAnR3RDL3llYXInKQpoaXN0KFlfbW1fbGlzdFtbMV1dJG1lYW4sIGFkZCA9IFRSVUUsIGNvbCA9ICdibGFjaycpCnBvbHlnb24oeCA9IGMoLTEwLCAxMDAsIDEwMCwgLTEwKSwgeSA9IGMoMCwgMCwgMTAwMCwgMTAwMCksCiAgICAgICAgY29sID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJyksCiAgICAgICAgYm9yZGVyID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJykpCnJ1ZyhZX3RhcmdldFsxXSwgY29sID0gJ2JsYWNrJykKcnVnKGMoWV90YXJnZXRbMV0gKyAzKmRpc2NzZFsxXSxZX3RhcmdldFsxXSAtIDMqZGlzY3NkWzFdKSAsIGNvbCA9ICdyZWQnKQoKaGlzdChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbnBwX25saW1fbG5kX3N1bSddLCBjb2wgPSBoY29sICwgbWFpbiA9ICdOUFAnLCB4bGFiID0gJ0d0Qy95ZWFyJykKaGlzdChZX21tX2xpc3RbWzJdXSRtZWFuLCBhZGQgPSBUUlVFLCBjb2wgPSAnYmxhY2snKQpwb2x5Z29uKHggPSBjKDM1LCA4MCwgODAsIDM1KSwgeSA9IGMoMCwgMCwgMTAwMCwgMTAwMCksCiAgICAgICAgY29sID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJyksCiAgICAgICAgYm9yZGVyID0gbWFrZVRyYW5zcGFyZW50KCd0b21hdG8yJykpCnJ1ZyhZX3RhcmdldFsyXSwgY29sID0gJ2JsYWNrJykKcnVnKGMoWV90YXJnZXRbMl0gKyAzKmRpc2NzZFsyXSxZX3RhcmdldFsyXSAtIDMqZGlzY3NkWzJdKSAsIGNvbCA9ICdyZWQnKQoKaGlzdChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnY1NvaWxfbG5kX3N1bSddLCBjb2wgPSBoY29sLCBtYWluID0gJ1NvaWwgQ2FyYm9uJywgeGxhYiA9ICdHdEMnKQpoaXN0KFlfbW1fbGlzdFtbM11dJG1lYW4sIGFkZCA9IFRSVUUsIGNvbCA9ICdibGFjaycpCnBvbHlnb24oeCA9IGMoNzUwLCAzMDAwLCAzMDAwLCA3NTApLCB5ID0gYygwLCAwLCAxMDAwLCAxMDAwKSwKICAgICAgICBjb2wgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSwKICAgICAgICBib3JkZXIgPSBtYWtlVHJhbnNwYXJlbnQoJ3RvbWF0bzInKSkKcnVnKFlfdGFyZ2V0WzNdLCBjb2wgPSAnYmxhY2snKQpydWcoYyhZX3RhcmdldFszXSArIDMqZGlzY3NkWzNdLFlfdGFyZ2V0WzNdIC0gMypkaXNjc2RbM10pICwgY29sID0gJ3JlZCcpCgpoaXN0KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjVmVnX2xuZF9zdW0nXSwgY29sID0gaGNvbCwgbWFpbiA9ICdWZWdldGF0aW9uIENhcmJvbicsIHhsYWIgPSAnR3RDJykKaGlzdChZX21tX2xpc3RbWzRdXSRtZWFuLCBhZGQgPSBUUlVFLCBjb2wgPSAnYmxhY2snKQpwb2x5Z29uKHggPSBjKDMwMCwgODAwLCA4MDAsIDMwMCksIHkgPSBjKDAsIDAsIDEwMDAsIDEwMDApLAogICAgICAgIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpLAogICAgICAgYm9yZGVyID0gIG1ha2VUcmFuc3BhcmVudCgndG9tYXRvMicpKQpydWcoWV90YXJnZXRbNF0sIGNvbCA9ICdibGFjaycpCnJ1ZyhjKFlfdGFyZ2V0WzRdICsgMypkaXNjc2RbNF0sWV90YXJnZXRbNF0gLSAzKmRpc2NzZFs0XSkgLCBjb2wgPSAncmVkJykKICAKYGBgCgoKSG93IGdvb2QgYXJlIHRoZSBmb3VyIGVtdWxhdG9ycyB0aGF0IHdlJ3ZlIGJ1aWx0PyBBcmUgdGhlcmUgYmlhc2VzPyAodGhlcmUncyBubyByZWFsIGV2aWRlbmNlIG9mIHRoaXMpCmBgYHtyLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gOH0KCnBhcihtZnJvdyA9IGMoMiwyKSkKCmZvcihpIGluIDE6NCl7CiAgCmhpc3Qod2F2ZTEkcHJlZF9saXN0W1tpXV0kbWVhbiwgbWFpbiA9IGNvbG5hbWVzKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpW2ldKQogIAp9CgoKYGBgCgojIyBPbmUtYXQtYS10aW1lIHNlbnNpdGl2aXR5IGFuYWx5c2lzIGZvciB1bmRlcnN0YW5kaW5nIG1vZGVsIHJlc3BvbnNlCkl0J3Mgb2J2aW91c2x5IGhhcmQgdG8gbWFpbnRhaW4gYSBoaWdoIHZlZ2V0YXRpb24gY2FyYm9uIGluIHBhcnRpY3VsYXIuIFdoYXQgcGFyYW1ldGVyIHZhbHVlcyBtaWdodCB5b3UgY2hvb3NlIHRvIGRvIHRoaXMsIGFuZCB3aGF0IG1pZ2h0IGJlIHRoZSB0cmFkZS1vZmZzIHlvdSBoYXZlIHRvIG1ha2U/CgoKYGBge3J9CgpYX29hYXRfbGV2ZWwxYSA8LSBvYWF0X2Rlc2lnbihYX2xldmVsMWEsIG49MjEsIG1lZCA9IFRSVUUpCmNvbG5hbWVzKFhfb2FhdF9sZXZlbDFhKSA9IGNvbG5hbWVzKFgpCgp5X29hYXQgPC0gcHJlZGljdC5rbSh3YXZlMSRmaXRfbGlzdFtbNF1dLCBuZXdkYXRhID0gWF9vYWF0X2xldmVsMWEsIHR5cGUgPSAnVUsnKQoKYGBgCgoKCgpGaXJzdCwgd2hhdCBwYXJhbWV0ZXJzIGFmZmVjdCB2ZWdldGF0aW9uIGNhcmJvbiBhbmQgaG93PyBIb3cgc3VyZSBhcmUgd2UgYWJvdXQgdGhhdD8KCmBgYHtyLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gMTB9CgoKb2FhdExpbmVQbG90KFhfb2FhdCA9IFhfb2FhdF9sZXZlbDFhLCB5X29hYXRfbWVhbiA9IHlfb2FhdCRtZWFuLCB5X29hYXRfc2QgPSB5X29hYXQkc2QsIAogICAgICAgICAgICAgbl9vYWF0ID0gMjEsbnIgPSA2LCBuYyA9IDYpIAoKCmBgYAoKCgpgYGB7cn0KCllfb2FhdF9jb25zdF9sZXZlbDFhX3NjYWxlZCA8LSBtYXRyaXgobmNvbCA9IG5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCksIG5yb3cgPSBucm93KFhfb2FhdF9sZXZlbDFhKSkKCmZvcihpIGluIDE6bmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSl7CgogIHlfb2FhdCA8LSBwcmVkaWN0LmttKHdhdmUxJGZpdF9saXN0W1tpXV0sIG5ld2RhdGEgPSBYX29hYXRfbGV2ZWwxYSwgdHlwZSA9ICdVSycpCiAgWV9vYWF0X2NvbnN0X2xldmVsMWFfc2NhbGVkWyxpXSA8LSB5X29hYXQkbWVhbgp9CgpgYGAKCgpXaGF0IG1pZ2h0IGJlIHRoZSB0cmFkZS1vZmZzIGZvciBhIGhpZ2ggKG9yIGFjY3VyYXRlKSB2ZWdldGF0aW9uIGNhcmJvbj8gYXJlIHRoZXkgYWNjZXB0YWJsZT8gUGxvdCB0aGUgb2FhdCBzZW5zaXRpdml0eSBvZiB0aGUgb3RoZXIgMyBvdXRwdXRzIHdlJ3JlIGNhbGlicmF0aW5nIG9uLiAKCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQgPSAxMH0KWV9vYWF0X2NvbnN0X2xldmVsMWFfc2NhbGVkX25vcm0gPC0gbm9ybWFsaXplKFlfb2FhdF9jb25zdF9sZXZlbDFhX3NjYWxlZCkKCm9hYXRMaW5lUGxvdE11bHRpKFhfb2FhdCA9IFhfb2FhdF9sZXZlbDFhLCBZX29hYXQgPSBZX29hYXRfY29uc3RfbGV2ZWwxYV9zY2FsZWRfbm9ybSAsICBuX29hYXQgPSAyMSwgbnIgPSA2LCBuYyA9IDYsCiAgICAgICAgICAgICAgICAgIGx3ZCA9IDIpCgpyZXNldCgpCmxlZ2VuZCgndG9wJywgYygnbmJwJywgJ25wcCcsICdjc29pbCcsICdjdmVnJyksIGNvbCA9IGMoMSwyLDMsNCksIGx0eSA9ICdzb2xpZCcsIGx3ZCA9IDIsIGhvcml6ID0gVFJVRSkKCgpgYGAKCgpXaGF0IGRvIHRoZSBlbXVsYXRvcnMgbWFrZSBvZiB0aGUgZGVzaWduIHBvaW50cyB3aGljaCBhY3R1YWxseSBtYWtlIEFuZHkncyAiaGFyZCBib3VuZGFyeSIgY3JpdGVyaWE/CklmIHdlIGxlYXZlIHRoZW0gb3V0LCBkbyB0aGV5IHN0aWxsIHBsYWNlIHRoZSBvdXRwdXQgd2l0aGluIHRoZSBoYXJkIGJvdW5kYXJpZXM/CgpgYGB7cn0KCiAgYXdfYm91bmRhcnlfaXggPSB3aGljaChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbmJwX2xuZF9zdW0nXSA+IC0xMCAmCiAgICAgICAgICAgICAgICAgICAgICBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbnBwX25saW1fbG5kX3N1bSddID4gMzUgJiAgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ25wcF9ubGltX2xuZF9zdW0nXSA8IDgwICYKICAgICAgICAgICAgICAgICAgICAgIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCdjU29pbF9sbmRfc3VtJ10gPiA3NTAgJiBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnY1NvaWxfbG5kX3N1bSddIDwgMzAwMCAmCiAgICAgICAgICAgICAgICAgICAgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddID4gMzAwICYgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddIDwgODAwCiAgICApCgoKClhfYXdfYm91bmRhcnkgPSBYX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsIF0KWV9hd19ib3VuZGFyeSA9IFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbYXdfYm91bmRhcnlfaXgsIF0KCmBgYAoKIyMgQ2hlY2sgdGhlIGVtdWxhdG9ycyB0aGF0IHByb2R1Y2UgdGhlIG5ldyBkZXNpZ24KRG8gYSBsZWF2ZS1vbmUtb3V0IGNyb3NzIHZhbGlkYXRpb24gb2YgcG9pbnRzIGluc2lkZSB0aGUgaGFyZCBib3VuZGFyaWVzIHVzaW5nIHRoZSB3YXZlMSBmaXRzLgpgYGB7cn0KIyBxdWlja2VzdCB0byBmaW5kIHRoZSBsb28gcHJlZGljdGlvbnMgYXQgdGhlIHJpZ2h0IGluZGljZXMKCgpgYGAKCmBgYHtyfQoKbG9vX21lYW5fWV9sZXZlbDFhIDwtIG1hdHJpeChucm93ID0gbnJvdyhYX2xldmVsMWEpLCBuY29sID0gbmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSkKbG9vX3NkX1lfbGV2ZWwxYSA8LSBtYXRyaXgobnJvdyA9IG5yb3coWF9sZXZlbDFhKSwgbmNvbCA9IG5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkpCiAgCiAgZm9yKGkgaW4gMTpuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKXsKCmxvbyA8LSBsZWF2ZU9uZU91dC5rbSh3YXZlMSRmaXRfbGlzdFtbaV1dLHR5cGUgPSAnVUsnLCB0cmVuZC5yZWVzdGltID0gVFJVRSApCiAgbG9vX21lYW5fWV9sZXZlbDFhWyxpXSA8LSBsb28kbWVhbgogIGxvb19zZF9ZX2xldmVsMWFbLGldIDwtIGxvbyRzZAp9CgpgYGAKCldlIHNlZSBpbiB0aGUgbGVhdmUtb25lLW91dCBhbmFseXNpcyB0aGF0IHRoZSBlbXVsYXRvciBpcyBjb25zaXN0ZW50bHkgdW5kZXItcHJlZGljdGluZyB0aGUgdmVnZXRhdGlvbiBjYXJib24gKHRob3VnaCB0aGUgdW5jZXJ0YWludHkgZXN0aW1hdGUgb2Z0ZW4gY292ZXJzIHRoZSBhY3R1YWwgdmFsdWUpLlRoaXMgc3VnZ2VzdHMgKDEpIHRoYXQgdGhlcmUgaXNuJ3QgcmVhbGx5IGEgaHVnZSBwcm9ibGVtIHdpdGggYSBtb2RlbCBkaXNjcmVwYW5jeSAob3IgYXQgbGVhc3QgdGhhdCBpc24ndCB0aGUgb25seSBwcm9ibGVtKSwgYW5kICgyKSB0aGUgaGlzdG9yeSBtYXRjaGluZyBpcyB3b3JraW5nIGFzIGl0IHNob3VsZCwgYW5kIHRha2luZyBpbnRvIGFjY291bnQgYSBub3QtZ3JlYXQgZW11bGF0b3IuCgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDh9CgpwYXIobWZyb3cgPSBjKDIsMikpCgpmb3IoaSBpbiAxOm5jb2wobG9vX21lYW5fWV9sZXZlbDFhKSl7CiAgCiAgcm4gPC0gcmFuZ2UoYyhsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gLSAoMipsb29fc2RfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSAsIGxvb19tZWFuX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSArICgyKmxvb19zZF9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0pICkpCiAgCiAgCiAgCiAgcGxvdChZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBpXSwgbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldLCB5bGltID0gcm4sIG1haW4gPSBjb2xuYW1lcyhZX2NvbnN0X2xldmVsMWFfc2NhbGVkKVtpXSwgeGxhYiA9ICdhY3R1YWwnLCB5bGFiID0gJ3ByZWRpY3RlZCcpCiAgCiAgc2VnbWVudHMoeDAgPSBZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBpXSwgeTAgPSBsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gLSAoMipsb29fc2RfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSAgLCB4MSA9IFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbYXdfYm91bmRhcnlfaXgsIGldICwgeTEgPSBsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gKyAoMipsb29fc2RfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSAsIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgnYmxhY2snLCA3MCkpCiAgYWJsaW5lKDAsMSkKICAKfQoKCmBgYAoKIyMgQ29tcGFyZSB0aGUgc3RyYWlnaHQga20gd2l0aCBhIHR3by1zdGVwIGVtdWxhdG9yCklzIGEgdHdvLXN0ZXAgZW11bGF0b3IgYW55IGJldHRlciBhdCBlbXVsYXRpbmcgdGhvc2UgY3J1Y2lhbCBwb2ludHMgd2hpY2ggZmFsbCB3aXRoaW4gYXcncyBoYXJkIGJvdW5kYXJpZXM/IEZpcnN0LCBjcmVhdGUgYSBsaXN0IG9mIGVtdWxhdG9yIGZpdHMuCgpgYGB7cn0KCmZpdGxpc3RfWV9jb25zdF9sZXZlbDFhX3NjYWxlZCA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSkKCmZvcihpIGluIDE6bmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSl7CiAgCiAgeSA8LSBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWyxpXQogIGZpdCA8LSB0d29TdGVwX2dsbW5ldChYID0gWF9sZXZlbDFhLCB5KQogIGZpdGxpc3RfWV9jb25zdF9sZXZlbDFhX3NjYWxlZFtbaV1dIDwtIGZpdAoKfQoKCmBgYAoKYGBge3J9Cmxvb19tZWFuX2dsbW5ldF9ZX2xldmVsMWEgPC0gbWF0cml4KG5yb3cgPSBucm93KFhfbGV2ZWwxYSksIG5jb2wgPSBuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKQpsb29fc2RfZ2xtbmV0X1lfbGV2ZWwxYSA8LSBtYXRyaXgobnJvdyA9IG5yb3coWF9sZXZlbDFhKSwgbmNvbCA9IG5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkpCiAgCiAgZm9yKGkgaW4gMTpuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKXsKCmxvbyA8LSBsZWF2ZU9uZU91dC5rbShmaXRsaXN0X1lfY29uc3RfbGV2ZWwxYV9zY2FsZWRbW2ldXSRlbXVsYXRvcix0eXBlID0gJ1VLJywgdHJlbmQucmVlc3RpbSA9IFRSVUUgKQogIGxvb19tZWFuX2dsbW5ldF9ZX2xldmVsMWFbLGldIDwtIGxvbyRtZWFuCiAgbG9vX3NkX2dsbW5ldF9ZX2xldmVsMWFbLGldIDwtIGxvbyRzZAp9CgpgYGAKCkl0IGRvZXNuJ3QgYXBwZWFyIHRoYXQgdGhlIHR3by1zdGVwIGVtdWxhdG9yIChoZXJlIHBsb3R0ZWQgaW4gcmVkKSBpcyBkb2luZyBhbnkgYmV0dGVyIHRoYW4gdGhlIHJlZ3VsYXIgZW11bGF0b3IuCmBgYHtyLCBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gOH0KcGFyKG1mcm93ID0gYygyLDIpKQoKZm9yKGkgaW4gMTpuY29sKGxvb19tZWFuX1lfbGV2ZWwxYSkpewogIAogIHJuIDwtIHJhbmdlKGMobG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldIC0gKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgLCBsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gKyAoMipsb29fc2RfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSApKQogIAogIAogIAogIHBsb3QoWV9jb25zdF9sZXZlbDFhX3NjYWxlZFthd19ib3VuZGFyeV9peCwgaV0sIGxvb19tZWFuX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSwgeWxpbSA9IHJuLCBtYWluID0gY29sbmFtZXMoWV9jb25zdF9sZXZlbDFhX3NjYWxlZClbaV0sIHhsYWIgPSAnYWN0dWFsJywgeWxhYiA9ICdwcmVkaWN0ZWQnKQogIAogIHBvaW50cyhZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBpXSwgbG9vX21lYW5fZ2xtbmV0X1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSwgY29sID0gJ3JlZCcpCiAgCiAgCiAgc2VnbWVudHMoeDAgPSBZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBpXSwgeTAgPSBsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gLSAoMipsb29fc2RfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSAgLCB4MSA9IFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbYXdfYm91bmRhcnlfaXgsIGldICwgeTEgPSBsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0gKyAoMipsb29fc2RfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSAsIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgnYmxhY2snLCA3MCkpCiAgYWJsaW5lKDAsMSkKICAKfQpgYGAKClR3byBvdGhlciB0aGluZ3MgSSBjYW4gdGhpbmsgb2YgdG8gY2hlY2s6IDEpIGhvdyBhYm91dCB1c2luZyAibXVsdGlzdGFydCIgdG8gY2hvb3NlIGRpZmZlcmVudCBzdGFydGluZyBjb25kaXRpb25zIGZvciBvcHRpbWlzaW5nIHRoZSBlbXVsYXRvcnMgYW5kIDIpIFVzaW5nIGEgZmxhdCBwcmlvciBmb3IgdGhlIG1lYW4gZnVuY3Rpb24gcmF0aGVyIHRoYW4gYSBsaW5lYXIgcHJpb3IuCmBgYHtyfQoKZml0bGlzdF9mbGF0cHJpb3JfWV9jb25zdF9sZXZlbDFhX3NjYWxlZCA8LSB2ZWN0b3IobW9kZSA9ICdsaXN0JywgbGVuZ3RoID0gbmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSkKCmZvcihpIGluIDE6bmNvbChZX2NvbnN0X2xldmVsMWFfc2NhbGVkKSl7CiAgCiAgeSA8LSBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWyxpXQogIGZpdCA8LSBrbShmb3JtdWxhID1+MSwgZGVzaWduID0gWF9sZXZlbDFhLCByZXNwb25zZSA9IHkpCiAgZml0bGlzdF9mbGF0cHJpb3JfWV9jb25zdF9sZXZlbDFhX3NjYWxlZFtbaV1dIDwtIGZpdAoKfQoKCmBgYAoKYGBge3J9Cmxvb19tZWFuX2ZsYXRwcmlvcl9ZX2xldmVsMWEgPC0gbWF0cml4KG5yb3cgPSBucm93KFhfbGV2ZWwxYSksIG5jb2wgPSBuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKQpsb29fc2RfZmxhdHByaW9yX1lfbGV2ZWwxYSA8LSBtYXRyaXgobnJvdyA9IG5yb3coWF9sZXZlbDFhKSwgbmNvbCA9IG5jb2woWV9jb25zdF9sZXZlbDFhX3NjYWxlZCkpCiAgCiAgZm9yKGkgaW4gMTpuY29sKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpKXsKCmxvbyA8LSBsZWF2ZU9uZU91dC5rbShmaXRsaXN0X2ZsYXRwcmlvcl9ZX2NvbnN0X2xldmVsMWFfc2NhbGVkW1tpXV0sdHlwZSA9ICdVSycsIHRyZW5kLnJlZXN0aW0gPSBUUlVFICkKICBsb29fbWVhbl9mbGF0cHJpb3JfWV9sZXZlbDFhWyxpXSA8LSBsb28kbWVhbgogIGxvb19zZF9mbGF0cHJpb3JfWV9sZXZlbDFhWyxpXSA8LSBsb28kc2QKfQoKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDh9CnBhcihtZnJvdyA9IGMoMiwyKSkKCmZvcihpIGluIDE6bmNvbChsb29fbWVhbl9ZX2xldmVsMWEpKXsKICAKICBybiA8LSByYW5nZShjKGxvb19tZWFuX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSAtICgyKmxvb19zZF9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0pICwgbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldICsgKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgKSkKICAKICAKICAKICBwbG90KFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbYXdfYm91bmRhcnlfaXgsIGldLCBsb29fbWVhbl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0sIHlsaW0gPSBybiwgbWFpbiA9IGNvbG5hbWVzKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQpW2ldLCB4bGFiID0gJ2FjdHVhbCcsIHlsYWIgPSAncHJlZGljdGVkJykKICAKICBwb2ludHMoWV9jb25zdF9sZXZlbDFhX3NjYWxlZFthd19ib3VuZGFyeV9peCwgaV0sIGxvb19tZWFuX2ZsYXRwcmlvcl9ZX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsaV0sIGNvbCA9ICdyZWQnKQogIAogIAogIHNlZ21lbnRzKHgwID0gWV9jb25zdF9sZXZlbDFhX3NjYWxlZFthd19ib3VuZGFyeV9peCwgaV0sIHkwID0gbG9vX21lYW5fWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldIC0gKDIqbG9vX3NkX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSkgICwgeDEgPSBZX2NvbnN0X2xldmVsMWFfc2NhbGVkW2F3X2JvdW5kYXJ5X2l4LCBpXSAsIHkxID0gbG9vX21lYW5fZmxhdHByaW9yX1lfbGV2ZWwxYVthd19ib3VuZGFyeV9peCxpXSArICgyKmxvb19zZF9mbGF0cHJpb3JfWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LGldKSAsIGNvbCA9IG1ha2VUcmFuc3BhcmVudCgnYmxhY2snLCA3MCkpCiAgYWJsaW5lKDAsMSkKICAKfQoKCgpgYGAKCgoKIyBFeHBsb3JpbmcgbmV3IGNvbnN0cmFpbnRzCklucHV0IGZyb20gRWRkeSBSb2JlcnRzb246CgoiV2UgY2FuIGFzc3VtZSB0aGF0IHRoZSBtYWpvcml0eSBvZiB2ZWdldGF0aW9uIGNhcmJvbiBpcyBzdG9yZWQgaW4gdHJlZSB0cnVua3Mgc28sIHRoZSBjYXJib24gZGVuc2l0eSBvZiB0cmVlcyBpcyBhcHByb3hpbWF0ZWx5IChjVmVnX2xuZF9tZWFuIC8gdHJlZUZyYWNfbG5kX21lYW4pLiBBbHRob3VnaCBJIHN1cHBvc2UgaXQncyBwb3NzaWJsZSB0aGF0IGluIHRoZSBQUEUgdGhlIHNocnVicyBoYXZlIGJlY29tZSB0cmVlLWxpa2UsIHNvIGl0IG1pZ2h0IGJlIGludGVyZXN0aW5nIHRvIHBsb3QgY1ZlZ19sbmRfbWVhbiB2ZXJzdXMgIChzaHJ1YkZyYWNfbG5kX21lYW4gKyB0cmVlRnJhY19sbmRfbWVhbikgYXMgd2VsbC4gVGhlIGZpcnN0IHF1ZXN0aW9uIGlzIHdoZXRoZXIgY1ZlZ19sbmRfbWVhbiBpbmNyZWFzZXMgbGluZWFybHkgd2l0aCB0cmVlRnJhY19sbmRfbWVhbi4gVGhlbiBpZiB0aGlzIHR1cm5lZCBvdXQgdG8gYmUgaW50ZXJlc3RpbmcsIHdlIGNvdWxkIHByb2R1Y2UgYSB0cmVlQ1ZlZ19sbmRfbWVhbiBvdXRwdXQuIgoKYGBge3IsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA3fQoKI3BkZihmaWxlID0gJ3ZlZ0NfZGVuc2l0eS5wZGYnLCB3aWR0aCA9IDYsIGhlaWdodCA9IDYpCnBsb3QoWV9sZXZlbDBbLCd0cmVlRnJhY19sbmRfbWVhbiddLFlfbGV2ZWwwWywnY1ZlZ19sbmRfbWVhbiddLCBtYWluID0gIlZlZ2V0YXRpb24gKHRyZWUpIGNhcmJvbiBkZW5zaXR5LCBMZXZlbDAiLAogICAgIHhsYWIgPSAndHJlZUZyYWNfbG5kX21lYW4nLCB5bGFiICA9ICdjVmVnX2xuZF9tZWFuJyApCgojZGV2Lm9mZigpCgpgYGAKCklzIHRoZSByYW5nZSBvZiBjYXJib24gZGVuc2l0aWVzIG5hcnJvd2VyIGluIHRoZSAiaGFyZCBib3VuZGFyeSIgc2V0PwpgYGB7ciwgZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDZ9CgpZX2xldmVsMWFfYXcgPC0gWV9sZXZlbDFhW2F3X2JvdW5kYXJ5X2l4LCBdClhfbGV2ZWwxYV9hdyA8LSBYX2xldmVsMWFbYXdfYm91bmRhcnlfaXgsIF0KCiNwZGYoZmlsZSA9ICd2ZWdDX2RlbnNpdHlfYXcucGRmJywgd2lkdGggPSA2LCBoZWlnaHQgPSA2KQpwbG90KFlfbGV2ZWwxYVssJ3RyZWVGcmFjX2xuZF9tZWFuJ10sWV9sZXZlbDFhWywnY1ZlZ19sbmRfbWVhbiddLCBtYWluID0gIlZlZ2V0YXRpb24gKHRyZWUpIGNhcmJvbiBkZW5zaXR5IiwKICAgICB4bGFiID0gJ3RyZWVGcmFjX2xuZF9tZWFuJywgeWxhYiAgPSAnY1ZlZ19sbmRfbWVhbicgKQoKcG9pbnRzKCBZX2xldmVsMWFfYXdbLCd0cmVlRnJhY19sbmRfbWVhbiddLFlfbGV2ZWwxYV9hd1ssJ2NWZWdfbG5kX21lYW4nXSwgcGNoID0gMTksIGNvbCA9ICdyZWQnKQpsZWdlbmQoJ3RvcGxlZnQnLCBsZWdlbmQgPSBjKCdMZXZlbDFhJywnQVcgY29uc3RyYWludHMnKSwgcGNoID0gYygyMSwgMTkpLCBjb2wgPSBjKCdibGFjaycsICdyZWQnKSkKIyAgIGRldi5vZmYoKQoKCgpgYGAKCgoKCmBgYHtyfQpjX2RlbnNpdHkgPC0gWV9sZXZlbDFhWywndHJlZUZyYWNfbG5kX21lYW4nXSAvIFlfbGV2ZWwxYVssJ2NWZWdfbG5kX21lYW4nXQoKaGlzdChjX2RlbnNpdHkpCgoKCmBgYAoKIyMgTm93IHRoYXQgd2UgaGF2ZSBjb25zdHJhaW50cywgd2UgY2FuIGV4cGxvcmUgdGhlaXIgZWZmZWN0IG9uIHRoZSBvdXRwdXQgCgpgYGB7ciwgZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSAyMH0KIyBQYWlycyBwbG90IG9mIG91dHB1dAp5X25hbWVzX21lYW4gPC0gYygnbmJwX2xuZF9tZWFuJywgJ2ZMdWNfbG5kX21lYW4nLCAnbnBwX25saW1fbG5kX21lYW4nLCAnY1NvaWxfbG5kX21lYW4nLAogICAgICAgICAgICAnY1ZlZ19sbmRfbWVhbicsICdsYW5kQ292ZXJGcmFjX2xuZF9tZWFuJywgJ2ZIYXJ2ZXN0X2xuZF9tZWFuJywKICAgICAgICAgICAgJ2xhaV9sbmRfbWVhbicsICdyaF9sbmRfbWVhbicsICd0cmVlRnJhY19sbmRfbWVhbicsICdjM1BmdEZyYWNfbG5kX21lYW4nLCAKICAgICAgICAgICAgJ2M0UGZ0RnJhY19sbmRfbWVhbicsICdzaHJ1YkZyYWNfbG5kX21lYW4nLCAnYmFyZXNvaWxGcmFjX2xuZF9tZWFuJykKCllfbGV2ZWwxYV9tZWFuIDwtIFlfbGV2ZWwxYVsseV9uYW1lc19tZWFuXQoKcGNvbCA8LSByZXAoJ2JsYWNrJywgbnJvdyhZX2xldmVsMWFfbWVhbikpCnBjb2xbYXdfYm91bmRhcnlfaXhdIDwtICdyZWQnCnBhaXJzKFlfbGV2ZWwxYV9tZWFuLCBjb2wgPSBwY29sLCBsb3dlci5wYW5lbCA9IE5VTEwsIHBjaCA9IDE5LCBjZXgubGFiZWxzID0gMS41KQoKCgoKYGBgCgojIyBIb3cgbXVjaCBkb2VzIGNvbnN0cmFpbmluZyBhbiBvdXRwdXQgY29uc3RyYWluIG90aGVyIG91dHB1dHM/CkZvciBleGFtcGxlLCB3aGF0IGVmZmVjdCBoYXMgdGhlIEFXICJoYXJkIGJvdW5kYXJ5IiBjb25zdHJhaW50IHByb2R1Y2VkIG9uIHJhbmdlcyBvZiB0aGUgb3RoZXIgKG1hcmdpbmFsKSBvdXRwdXRzPyBXaGljaCBjb25zdHJhaW50IGlzIGRvaW5nIHRoZSBtYWpvcml0eSBvZiB0aGUgd29yaz8KCgpBIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIHByb3BvcnRpb24gb2Ygb3V0cHV0IHNwYWNlIHRoYXQgaXMgcmVtb3ZlZCAob3IgcmV0YWluZWQpIHdoZW4gYXBwbHlpbmcgYSBjb25zdHJhaW50LgpgYGB7cn0KCmNvbnN0cmFpbnRfcHJvcCA8LSBmdW5jdGlvbihZLCBjb25zdHJhaW50X2l4KXsKICAKICBZY29uc3QgPC0gWVtjb25zdHJhaW50X2l4LCBdCiAgWWNvbnN0X25vcm0gPC0gbm9ybWFsaXplKFljb25zdCwgd3J0ID0gWSkKICBybiA8LSBhcHBseShZY29uc3Rfbm9ybSwgMiwgcmFuZ2UpCiAgb3V0IDwtIHJuCiAgb3V0CiAgCn0KCgpgYGAKCmBgYHtyfQpZX2NvbnN0cmFpbnRfcGxvdCA8LSBmdW5jdGlvbihjb25zdHJhaW50X3JhbmdlLCBjb25zdHJhaW50X2NvbHVtbnMsIC4uLil7CiAgIyBBIGZ1bmN0aW9uIHRvIHBsb3QgdGhlIG91dHB1dCBvZiBjb25zdHJhaW50X3Byb3AKICAKICBwYXIobWFyID0gYygxMiw0LDMsMiksbGFzID0gMikKCnBjb2wgPSByZXAoJ2JsYWNrJywgbmNvbChjb25zdHJhaW50X3JhbmdlKSkKcGNvbFtjb25zdHJhaW50X2NvbHVtbnNdIDwtICdyZWQnICMgcGxvdCB0aGUgb3V0cHV0cyB3aGVyZSB3ZSBoYXZlIHNwZWNpZmllZCB0aGUgY29uc3RyYWludHMgaW4gcmVkLgoKcGxvdCgxOm5jb2woY29uc3RyYWludF9yYW5nZSksY29uc3RyYWludF9yYW5nZVsyLF0sIHlsaW0gPSBjKDAsMSkgLCBheGVzID0gRkFMU0UsIHhsYWIgPSAnJywgeWxhYiA9ICdyYW5nZSBvZiBlbnNlbWJsZSAoZnJhY3Rpb24pJywgY29sID0gcGNvbCwgcGNoID0gMTksIC4uLikKcG9pbnRzKDE6bmNvbChjb25zdHJhaW50X3JhbmdlKSwgY29uc3RyYWludF9yYW5nZVsxLF0sIGNvbCA9IHBjb2wsIHBjaCA9IDE5KQpzZWdtZW50cyh4MCA9IDE6bmNvbChjb25zdHJhaW50X3JhbmdlKSwgeTAgPSBjb25zdHJhaW50X3JhbmdlWzEsXSwgeDEgPSAxOm5jb2woY29uc3RyYWludF9yYW5nZSksIHkxID0gY29uc3RyYWludF9yYW5nZVsyLF0sIGNvbCA9IHBjb2wsIGx3ZCA9MiApCgpheGlzKHNpZGUgPSAxLCBsYWJlbHMgPSBjb2xuYW1lcyhjb25zdHJhaW50X3JhbmdlKSwgYXQgPSAxOm5jb2woY29uc3RyYWludF9yYW5nZSkpCmF4aXMoMikKYWJsaW5lKGggPSBjKDAsMSksIGNvbCA9ICdyZWQnKQogIAp9CmBgYAoKQWxsIGNvbnN0cmFpbnRzIHRvZ2V0aGVyIHRha2UgdGhlIG5vcm1hbGl6ZWQgcmFuZ2Ugb2YgYWxsIHRoZSBvdXRwdXRzIHRvIGEgbGl0dGxlIHVuZGVyIGEgaGFsZiBvZiB0aGUgb3JpZ2luYWwgcmFuZ2UsIG9uIGF2ZXJhZ2UuIE9mIGNvdXJzZSwgZm91ciBvZiB0aGUgaW5wdXRzIGFyZSBjb25zdHJhaW5lZCBoZXJlLCB3aGljaCBoYXMgcXVpdGUgYSBsYXJnZSBpbXBhY3QuCmBgYHtyfQpZX2xldmVsMWFfbWVhbl9hd19ub3JtX3JuIDwtIGNvbnN0cmFpbnRfcHJvcChZID0gWV9sZXZlbDFhX21lYW4sIGNvbnN0cmFpbnRfaXggPSBhd19ib3VuZGFyeV9peCkKbWVhbl9jb25zdHJhaW50X2FsbCA8LSBtZWFuKFlfbGV2ZWwxYV9tZWFuX2F3X25vcm1fcm5bMiwgXSAtIFlfbGV2ZWwxYV9tZWFuX2F3X25vcm1fcm5bMSwgXSkKWV9jb25zdHJhaW50X3Bsb3QoWV9sZXZlbDFhX21lYW5fYXdfbm9ybV9ybixjb25zdHJhaW50X2NvbHVtbnMgPSBjKGMoMSwzLDQsNSkpLCBtYWluID0gcGFzdGUoJ21lYW4gY29uc3RyYWluZWQgcmFuZ2UgPScsIHJvdW5kKG1lYW5fY29uc3RyYWludF9hbGwsMykpKQpgYGAKCldlIGNhbiBzZWUgd2hhdCBpbXBhY3RzIHRoZSBjb25zdHJhaW50cyBoYXZlIGluZGl2aWR1YWxseQpgYGB7cn0KCm5icF9peCA8LSB3aGljaChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbmJwX2xuZF9zdW0nXSA+IC0xMCkKbnBwX2l4IDwtIHdoaWNoKFlfY29uc3RfbGV2ZWwxYV9zY2FsZWRbLCducHBfbmxpbV9sbmRfc3VtJ10gPiAzNSAmICBZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnbnBwX25saW1fbG5kX3N1bSddIDwgODAgKQpjU29pbF9peCA8LSB3aGljaChZX2NvbnN0X2xldmVsMWFfc2NhbGVkWywnY1NvaWxfbG5kX3N1bSddID4gNzUwICYgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NTb2lsX2xuZF9zdW0nXSA8IDMwMDApCmNWZWdfaXggPC0gd2hpY2goWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddID4gMzAwICYgWV9jb25zdF9sZXZlbDFhX3NjYWxlZFssJ2NWZWdfbG5kX3N1bSddIDwgODAwKQoKYGBgCgpUaGUgTkJQIGNvbnN0cmFpbnQgaGFzIG5vIG1hcmdpbmFsIGltcGFjdApgYGB7cn0KCllfbGV2ZWwxYV9tZWFuX25icF9jb25zdCA8LSBjb25zdHJhaW50X3Byb3AoWSA9IFlfbGV2ZWwxYV9tZWFuLCBjb25zdHJhaW50X2l4ID0gbmJwX2l4ICkKbWVhbl9jb25zdHJhaW50X25icCA8LSBtZWFuKFlfbGV2ZWwxYV9tZWFuX25icF9jb25zdFsyLCBdIC0gWV9sZXZlbDFhX21lYW5fbmJwX2NvbnN0WzEsIF0pCllfY29uc3RyYWludF9wbG90KFlfbGV2ZWwxYV9tZWFuX25icF9jb25zdCwxLCAgbWFpbiA9IHBhc3RlKCdtZWFuIGNvbnN0cmFpbmVkIHJhbmdlID0nLCByb3VuZChtZWFuX2NvbnN0cmFpbnRfbmJwLDMpKSkKCmBgYAoKYGBge3J9CgpZX2xldmVsMWFfbWVhbl9ucHBfY29uc3QgPC0gY29uc3RyYWludF9wcm9wKFkgPSBZX2xldmVsMWFfbWVhbiwgY29uc3RyYWludF9peCA9IG5wcF9peCApCm1lYW5fY29uc3RyYWludF9ucHAgPC0gbWVhbihZX2xldmVsMWFfbWVhbl9ucHBfY29uc3RbMiwgXSAtIFlfbGV2ZWwxYV9tZWFuX25wcF9jb25zdFsxLCBdKQpZX2NvbnN0cmFpbnRfcGxvdChZX2xldmVsMWFfbWVhbl9ucHBfY29uc3QsMywgIG1haW4gPSBwYXN0ZSgnbWVhbiBjb25zdHJhaW5lZCByYW5nZSA9Jywgcm91bmQobWVhbl9jb25zdHJhaW50X25wcCwzKSkpCgpgYGAKCgpgYGB7cn0KCllfbGV2ZWwxYV9tZWFuX2NTb2lsX2NvbnN0IDwtIGNvbnN0cmFpbnRfcHJvcChZID0gWV9sZXZlbDFhX21lYW4sIGNvbnN0cmFpbnRfaXggPSBjU29pbF9peCApCm1lYW5fY29uc3RyYWludF9jU29pbCA8LSBtZWFuKFlfbGV2ZWwxYV9tZWFuX2NTb2lsX2NvbnN0WzIsIF0gLSBZX2xldmVsMWFfbWVhbl9jU29pbF9jb25zdFsxLCBdKQpZX2NvbnN0cmFpbnRfcGxvdChZX2xldmVsMWFfbWVhbl9jU29pbF9jb25zdCw0LCAgbWFpbiA9IHBhc3RlKCdtZWFuIGNvbnN0cmFpbmVkIHJhbmdlID0nLCByb3VuZChtZWFuX2NvbnN0cmFpbnRfY1NvaWwsMykpKQoKYGBgClZlZ2V0YXRpb24gY2FyYm9uIChjVmVnKSBoYXMgdGhlIHN0cm9uZ2VzdCBpbXBhY3Qgb24gZXZlcnl0aGluZyBlbHNlLiBUaGlzIGlzIG5vIHN1cHJpc2UsIGdpdmVuIHRoYXQgc28gZmV3IG9mIHRoZSBlbnNlbWJsZSBtZW1iZXJzIHNlZW0gdG8gc2ltdWxhdGUgY2FyYm9uIHZlZ2V0YXRpb24gaGlnaCBlbm91Z2guCmBgYHtyfQoKWV9sZXZlbDFhX21lYW5fY1ZlZ19jb25zdCA8LSBjb25zdHJhaW50X3Byb3AoWSA9IFlfbGV2ZWwxYV9tZWFuLCBjb25zdHJhaW50X2l4ID0gY1ZlZ19peCApCm1lYW5fY29uc3RyYWludF9jVmVnIDwtIG1lYW4oWV9sZXZlbDFhX21lYW5fY1ZlZ19jb25zdFsyLCBdIC0gWV9sZXZlbDFhX21lYW5fY1ZlZ19jb25zdFsxLCBdKQpZX2NvbnN0cmFpbnRfcGxvdChZX2xldmVsMWFfbWVhbl9jVmVnX2NvbnN0LDUsICBtYWluID0gcGFzdGUoJ21lYW4gY29uc3RyYWluZWQgcmFuZ2UgPScsIHJvdW5kKG1lYW5fY29uc3RyYWludF9jVmVnLDMpKSkKCmBgYAoKYGBge3J9CgojIHdpdGggMyBwcm9jZXNzZXJzLCB1c2luZyBmb3JlYWNoIHBhcmFsbGVsIHByb2Nlc3NpbmcgdGFrZXMgYXBwcm94aW1hdGVseSAxLzMgdGhlIHRpbWUgKGFyb3VuZCAyMCBzZWNvbmRzIHBlciBlbXVsYXRvcikgb2YgbG9vcGluZyB0aGUgZW11bGF0b3IgZml0dGluZyBkaXJlY3RseS4gSSdkIGhvcGUgdGhpcyB3b3VsZCBzY2FsZSB3aXRoIHByb2Nlc3NvciBudW1iZXJzIC0gaXQnbGwgYmUgd29ydGggdHJ5aW5nIG9uIFNQSUNFLgoKIyBzeXN0ZW0udGltZSh0ZXN0bG9vcF9wYXIgPC0gZGlyZWN0X3R3b1N0ZXBfZ2xtbmV0X3BhcmFsbGVsKFg9WF9sZXZlbDEsIFkgPSBZX2xldmVsMSkpCgpgYGAKCgojIyBXcml0aW5nIHJvYnVzdCwgcGFyYWxsZWxpc2VkLCBtdWx0aXN0YXJ0ICBlbXVsYXRvcnMKYGBge3J9CmRpcmVjdF90d29TdGVwX2dsbW5ldCA8LSBmdW5jdGlvbihYLCBZLCAuLi4pewogIAogIGQgPC0gbmNvbChZKQogIAogIG91dCA8LSB2ZWN0b3IobW9kZT0nbGlzdCcsIGxlbmd0aD1kKQogIAogIGZvcihpIGluIDE6ZCl7CiAgICAKICAgIHkgPC0gWVssaV0KICAgIAogICAgZW0gPC0gdHdvU3RlcF9nbG1uZXQoWD1YLCB5ID0geSwgLi4uKQogICAgb3V0W2ldIDwtIGVtCiAKICB9CiAgCiAgb3V0Cn0gCgoKYGBgCgoKIyBEaXJlY3QgdHdvU3RlcCBlbXVsYXRvciB1c2luZyBmb3JlYWNoCmBgYHtyfQoKbGlicmFyeShkb1BhcmFsbGVsKQpyZWdpc3RlckRvUGFyYWxsZWwoY29yZXMgPSBkZXRlY3RDb3JlcygpIC0gMSkKCmRpcmVjdF90d29TdGVwX2dsbW5ldF9wYXJhbGxlbCA8LSBmdW5jdGlvbihYLCBZLCAuLi4pewogIAogIGQgPC0gbmNvbChZKQogIAogIG91dCA8LSB2ZWN0b3IobW9kZT0nbGlzdCcsIGxlbmd0aD1kKQogIAogIGZvcmVhY2goaSA9IDE6ZCkgJWRvcGFyJSB7CiAgICAKICAgIHkgPC0gWVssaV0KICAgIAogICAgZW0gPC0gdHdvU3RlcF9nbG1uZXQoWD1YLCB5ID0geSwgLi4uKQogICAgb3V0W2ldIDwtIGVtCiAKICB9CiAgCiAgb3V0Cn0gCgpgYGAKCgoKYGBge3J9CgojIEkgYWN0dWFsbHkgd3JvdGUgY29kZSB0byBkbyB0aGlzIGNyZWF0ZUttRml0TGlzdCwgd2hpY2ggaXNuJ3QgcGFyYWxsZWwgYXQgdGhlIG1vbWVudC4KIyBNYXliZSBtYWtlIGl0IHBhcmFsbGVsIGluIHRoZSBuZXh0IHZlcnNpb24/CgpsaWJyYXJ5KGRvUGFyYWxsZWwpCnJlZ2lzdGVyRG9QYXJhbGxlbChjb3JlcyA9IGRldGVjdENvcmVzKCkgLSAxKQoKZGlyZWN0X3R3b1N0ZXBfZ2xtbmV0X3BhcmFsbGVsIDwtIGZ1bmN0aW9uKFgsIFksIC4uLil7CiAgCiAgZCA8LSBuY29sKFkpCiAgZm9yZWFjaChpID0gMTpkKSAlZG9wYXIlIHsKICAgIAogICAgeSA8LSBZWyxpXQogICAgCiAgICBlbSA8LSB0d29TdGVwX2dsbW5ldChYPVgsIHkgPSB5LCAuLi4pCiAgfQp9IAoKCgpgYGAKCgoKYGBge3J9CgpsaWJyYXJ5KGRvUGFyYWxsZWwpCmNvcmVzPWRldGVjdENvcmVzKCkKY2wgPC0gbWFrZUNsdXN0ZXIoY29yZXNbMV0tMSkgI25vdCB0byBvdmVybG9hZCB5b3VyIGNvbXB1dGVyCnJlZ2lzdGVyRG9QYXJhbGxlbChjbCkKCmZpdGxpc3RfdGVzdCA8LSBjcmVhdGVLbUZpdExpc3RQYXJhbGxlbChYID0gWF9sZXZlbDFhLCBZID0gIFlfY29uc3RfbGV2ZWwxYV9zY2FsZWQsIGZvcm11bGEgPSB+LiwgbXVsdGlzdGFydCA9IDQpCnN0b3BDbHVzdGVyKGNsKQoKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNywgZmlnLmhlaWdodCA9IDl9CgoKcGxvdChmaXRsaXN0X3Rlc3RbWzRdXSkKYGBgCgoKYGBge3J9Cgojc3VtbWFyaXNlS21Mb28gPC0gZnVuY3Rpb24oZml0KXsKICAKIyAgbG9vIDwtIGxlYXZlT25lT3V0LmttKGZpdCwgdHlwZSA9ICdVSycsIHRyZW5kLnJlZXN0aW0gPSBUUlVFKQogIAojICBsb29fbWVhbiA8LSBtZWFuKGxvbyQpCiAgCiAgCiN9CgoKCmBgYAoKCgoKCmBgYHtyfQoKIyBzeXN0ZW0udGltZSh0ZXN0bG9vcCA8LSBkaXJlY3RfdHdvU3RlcF9nbG1uZXQoWD1YX2xldmVsMSwgWV9sZXZlbDEpKQoKYGBgCgoKCmBgYHtyfQojIFRlc3QgcGFyYWxsZWwgcHJvY2Vzc2luZyBhZ2FpbnN0IGEgZm9yZWFjaCBwcm9jZXNzaW5nIChhbmQgbWF5YmUgbWNsYXBwbHk/KQoKI3N5c3RlbS50aW1lKHRlc3Rsb29wX3BhciA8LSBkaXJlY3RfdHdvU3RlcF9nbG1uZXRfcGFyYWxsZWwoWD1YX2xldmVsMSwgWV9sZXZlbDEpKQoKCgpgYGAKCgpgYGB7cn0KZW1MaXN0IDwtIGZ1bmN0aW9uKFgsIFkpewogICMgQ3JlYXRlIGEgbGlzdCBvZiBvYmplY3RzIHRvIGJlIGVtdWxhdGVkCiAgIyBYICAgICAgICAgICAgIGRlc2lnbiBtYXRyaXggd2l0aCAobnJvdykgaW5zdGFuY2VzIG9mIChuY29sKSBpbnB1dHMKICAjIFkgICAgICAgICAgICAgbWF0cml4IG9mIG91dHB1dHMsIHdpdGggb25lIHJvdwogICMgICAgICAgICAgICAgICBmb3IgZWFjaCByb3cgb2YgWAoKICBkIDwtIG5jb2woWSkKICBlbV9saXN0IDwtIHZlY3Rvcihtb2RlPSdsaXN0JywgbGVuZ3RoPWQpCgogIGZvcihpIGluIDE6ZCl7CiAgICBlbV9vYmogPC0gTlVMTAogICAgZW1fb2JqJFggPC0gWAogICAgZW1fb2JqJHkgPC0gWVssIGldCiAgICBlbV9saXN0W1tpXV0gPC0gZW1fb2JqCiAgfQogIGVtX2xpc3QKfQpgYGAKCmBgYHtyfQoKCiN0ZXN0IDwtIGVtbGlzdChYX2xldmVsMSwgWV9sZXZlbDEpCgoKYGBgCgpgYGB7cn0KCiNtY2xhcHBseShYID0gdGVzdCwgRlVOID0ga20pCgoKYGBgCgoKCmBgYHtyfQoKIyBmdW5jdGlvbiBmcm9tIGhkZSBmb3IgZGlyZWN0IHByZWRpY3Rpb24KZGlyZWN0LnByZWQgPSBmdW5jdGlvbiAoZm9ybSwgWCwgWSwgWG5ldywgLi4uKXsKICAjIERpcmVjdGx5IGFwcGxpZXMga20gaW4gcGFyYWxsZWwgdG8gcHJlZGljdCBlYWNoIGNvbHVtbiBvZiBhbiBlbnNlbWJsZQogIGVucy5saXN0ID0gZW1saXN0KFggPSBYLCBZID0gWSkKICBrbS5saXN0ID0gbWNsYXBwbHkoZW5zLmxpc3QsIEZVTiA9IGttLndyYXAsIGZvcm0gPSBmb3JtKQoKICBwcmVkLmxpc3QgPSBtY2xhcHBseShrbS5saXN0LCBGVU4gPSBrbS5wcmVkLndyYXAsIFhuZXcgPSBhcy5tYXRyaXgoWG5ldywgbnJvdyA9IDEpLCB0eXBlID0gIlVLIikKCiAgb3V0Lm1lYW4gPSBzYXBwbHkocHJlZC5saXN0LCBGVU49ZXh0cmFjdC5wcmVkbWVhbikKICBvdXQuc2QgPSBzYXBwbHkocHJlZC5saXN0LCBGVU49ZXh0cmFjdC5wcmVkc2QpCiAgcmV0dXJuKGxpc3QobWVhbiA9IG91dC5tZWFuLCBzZCA9IG91dC5zZCkpCn0KCgoKYGBgCgoKCgoKCgo=